Vishant Bhatia(0798567), Tulaib Bin Ayyub(0789141), Alisha Mahajan(0802631)

We,Vishant Bhatia, Tulaib Bin Ayyub, and Alisha Mahajan hereby state that we have not communicated with or gained information in any way from any person or resource that would violate the College’s academic integrity policies, and that all work presented is our own. In addition, we also agree not to share our work in any way, before or after submission, that would violate the College’s academic integrity policies.

R version used- R version 4.2.1 (2022-06-23 ucrt)

RStudio used- 2022.07.1 version

List of R packages used- tidyverse, here, plotly, ggplot2.

Library Imported and their versions
  • tidyverse : 1.3.2
  • here : 1.0.1
  • plotly : 4.10.0
  • ggplot2 : 3.3.6
  • Contribution of each member:

  • Prepared one Histogram plot displaying distribution about a single numerical variable i.e Age of Winning Candidates.
  • Prepared one Box plot displaying information about outliers of above numerical variable.
  • Prepared one Bar chart displaying count information about one categorical variable i.e Category of winning candidates.
  • Prepared one Pie chart displaying proportions information about above categorical variable.
  • Prepared one Scatter Plot displaying information about pair of Numerical variable Age and General Votes.
  • Prepared one Scatter Plot displaying information about pair of one Numerical variable Age and one categorical variable Category.

  • Prepared one Histogram plot displaying distribution about a single numerical variable i.e Postal Votes.
  • Prepared one Box plot displaying information about outliers of above numerical variable.
  • Prepared one Bar chart displaying count information about one categorical variable i.e State.
  • Prepared one Pie chart displaying proportions information about above categorical variable.
  • Prepared one Scatter Plot displaying information about pair of Numerical variable Age and Postal Votes.
  • Prepared one Scatter Plot displaying information about pair of one Numerical variable Age and one categorical variable Winner

  • Prepared one Histogram plot displaying distribution about a single numerical variable i.e General Votes.
  • Prepared one Box plot displaying information about outliers of above numerical variable.
  • Prepared one Bar chart displaying count information about one categorical variable i.e Education of candidates.
  • Prepared one Pie chart displaying proportions information about above categorical variable.
  • Prepared one Scatter Plot displaying information about pair of Numerical variable Age and Total Votes.
  • Prepared one Scatter Plot displaying information about pair of one Numerical variable Age and one categorical variable State

  • Dataset: Indian Election 2019

    https://www.kaggle.com/code/paramarthasengupta/eda-plotly-prediction-indian-elections-2019

    Datatypes and Variables
  • STATE—-chr type
  • CONSTITUENCY—-chr type
  • NAME—-chr type
  • WINNER—-int type
  • PARTY—-chr type
  • SYMBOL—-chr type
  • GENDER—-chr type
  • CRIMINAL.CASES—-chr type
  • AGE—-int type
  • CATEGORY—-chr type
  • EDUCATION—-chr type
  • ASETS—-chr type
  • LIABILITIES—-chr type
  • GENERAL.VOTES—-int type
  • POSTAL.VOTES—-int type
  • TOTAL.VOTES—-int type
  • OVER.TOTAL.ELECTORS.IN.CONSTITUENCY→ num type
  • OVER.TOTAL.VOTES.POLLED..IN.CONSTITUENCY→ num type
  • TOTAL.ELECTORS—-int type

  • library("tidyverse")
    library("here")
    library("plotly")
    library("ggplot2")
    library("plotrix")
    setwd("C:\\F Drive\\BAsic stats DAB 501\\Project 2")




    indian_election_df <- read.csv("Indian_Election_2019.csv") 
    
    #indian_election_df
    

    1. Create an appropriate plot to visualize the distribution of this variable.

    indian_election_df_winner <- indian_election_df %>% 
                                    filter(WINNER == 1)
    
    # here we are filtering out data only of winning candidates of Indian Election 2019
    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = AGE)) +
      geom_histogram(binwidth = 3,color = "yellow",fill = "red")+
      labs(title="Distribution of Ages for Winning Candidate", 
           y = "Count", x = "Age of Winning Candidate") )
    NA

    In Above Histogram plot we can say that there are many winning candidates in Indian Election 2019 most of the ages are lies between 45-69.

    2. Consider any outliers present in the data. If present, specify the criteria used to identify them and provide a logical explanation for how you handled them.

    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(y = AGE)) +
      geom_boxplot(color = "Red", fill = "cyan")+
      labs(title="Distribution of Ages for Winning Candidate", 
           x = "Count", y = "Age of Winning Candidate"))
    NA
    NA
    NA

    In Above box plot we can clearly see that Median of winning candidates of Indian Election 2019 is 55, and most of the data lies between 47-63 age.

    There are many ways to find Outliers in above boxplot but the accurate way is:

    1. First we have to find the distance between First Quartile (Q1) and Third Quartile (Q3), which is called Interquartile (IQR)

    2. Anything which is beyond Q3 + 1.5 times the IQR and anything which is less than Q1 - 1.5 times the IQR gives the possible outliers.These are those observations which are away from box.

    3.Most Probable outliers are those values that are more than or less than above statement.

    For Example in our above BoxPlot:- Q1 = 47 Q3 = 63 IQR = Q3-Q1 = 16

    possible outliers are values > = Q3 + 1.5 * IQR called capping and values < = Q1 - 1.5 * IQR calling flooring

    Values > = 87 (capping) values < = 23 (flooring)

    According to this formula and after studying above histogram plot we can say that we have one outlier that is 87 and it’s count is 1.

    There are many ways to handle outliers.

    First is we can remove that record.But it is not recommended.

    Second way is if there are so many outliers values we can assign the value nearer to that outlier. for example if values are greater than 99 percentile then we can assign the 99th percentile value, and if value is less than 1 percentile then we can assign the 1st percentile value to that outlier.

    Third way is assign that value which is nearer to the median and outlier.

    3. Describe the shape and skewness of the distribution

    Ans–> In our 1st question we make histogram plot. The shape of Histogram is somehow symmetry and bell shaped.

    4. Based on your answer to the previous question, decide if it is appropriate to apply a transformation to your data. If no, explain why not. If yes, name the transformation applied and visualize the transformed distribution.

    summary(indian_election_df_winner$AGE)
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      26.00   47.00   55.00   54.44   63.00   86.00 
    summary(log10(indian_election_df_winner$AGE))
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1.415   1.672   1.740   1.726   1.799   1.934 
    summary(sqrt(indian_election_df_winner$AGE))
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      5.099   6.856   7.416   7.339   7.937   9.274 
    indian_election_df_winner$log_age <- log10(indian_election_df_winner$AGE)
    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = log_age)) +
      geom_histogram(color = "yellow",fill = "red",bins = 20)+
      labs(title="Distribution of Log10(Ages) for Winning Candidate", 
           y = "Count", x = "Log10(Age of Winning Candidate)") )
    NA
    
    indian_election_df_winner$sqrt_age <- sqrt(indian_election_df_winner$AGE)
    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = sqrt_age)) +
      geom_histogram(color = "yellow",fill = "red",bins = 20)+
      labs(title="Distribution of SQRT(Ages) for Winning Candidate",
           y = "Count", x = "SQRT(Age of Winning Candidate)") )
    NA

    By comparing above three histograms one from 1st question and other two are from Log10 and SQRT, we can say that there is no need of transformation of our original data as the distribution is symmetry and bell shaped in our original histogram.

    5. Choose and calculate an appropriate measure of central tendency.

    Ans–> The word “central tendancy” is fairly common in statistics. It’s a technique to explain how your data are distributed. While central tendancy does not provide you with the fine details of your data, it does provide you with a general notion of how your data are distributed.

    The mean, median, and mode are the three most widely used parameters of central tendency. The median of an ordered dataset is the value in the centre, whereas the mean or average is equal to the sum of all the values in the data set divided by the number of values in the data set. On the other side, mode shows you the dataset’s most repeatable value. So in our case we are using mean as central tendency.

    mean(indian_election_df_winner$AGE)
    [1] 54.44156

    6. Explain why you chose this as your measure of central tendency. Provide supporting evidence for your choice.

    Because age is an issue and we need to know the average age of the candidates who would win the 2019 Indian Election, we have chosen “Mean” as the central tendency. The victorious candidates’ average age is now 54.44. Since the mean and median values in this situation are about equal, we can also compute the median here. We are using visualisation to demonstrate this proof (Box plot and Histogram).

    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(y = AGE)) +
      geom_boxplot(color = "Red", fill = "cyan")+
      labs(title="Distribution of Ages for Winning Candidate", 
           x = "Count", y = "Age of Winning Candidate"))
    NA

    In above boxplot it is clearly shown that median of age is 55.

    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = AGE)) +
      geom_histogram(binwidth = 3,color = "yellow",fill = "red")+
      labs(title="Distribution of Ages for Winning Candidate", 
           y = "Count", x = "Age of Winning Candidate") )
    NA

    In above Histogram we can say that mean is just near about 54.50.

    7. Choose and calculate a measure of spread that is appropriate for your chosen measure of central tendency. Explain why you chose this as your measure of spread.

    We have following factors for measure of spread or measure of dispersion 1. Range 2. Inter-Quartile Range 3. Variance 4. Mean Deviation 5. Standard Deviation

    sd(indian_election_df_winner$AGE)
    [1] 11.04964

    In above question we use Standard Deviation because When data is distributed relatively normally, the standard deviation performs exceptionally well and provides information similar to that of the IQR. But the IQR is typically favored for data that is obviously non-normal.But in our case Age is just normally distributed.


      Categorical Variable : CATEGORY


    For each categorical variable :

    1. Create an appropriate plot to visualize the distribution of counts for this variable.

    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = CATEGORY)) +
      geom_bar(color = "black",fill = "cyan")+
      labs(title="Count of Different Categories of Winning Candidate", 
           y = "Count", x = "Category") )
    NA
    NA

    2. Create an appropriate plot to visualize the distribution of proportions for this variable.

    pie_data <- table(indian_election_df_winner$CATEGORY)
    
    
    
    lbls <- paste(names(pie_data), "\n", pie_data, sep="")
    
    pie3D(pie_data, labels = lbls, 
          main = "Proportions of Different Categories of Winning Candidate")

    NA
    NA
    NA

    3. Discuss any unusual observations for this variable?

    Ans–> There is only one unusual observation in above categorical variable. Out of 539, 55 are from ST category or we can say that aprox only 10 % of candidates are from ST category which is like an outlier of our data.

    4. Discuss if there are too few/too many unique values?

    Ans-> There are only 3 unique values in our categorical variable i.e General Category, SC Category and ST Category.

    unique(indian_election_df_winner$CATEGORY)
    [1] "ST"      "SC"      "GENERAL"

      Bivariate Analysis


      One pair of Numeric Variable : AGE and General Votes


      One pair of Numeric and Categorical Variable : AGE and Category


    1. Create an appropriate plot to visualize the relationship between the two variables.

    1. For 1st Pair
    indian_election_df_winner <- indian_election_df_winner %>% mutate(GENERAL.VOTES=GENERAL.VOTES/10000)
    
    
    
    ggplotly(indian_election_df_winner_sort %>% 
            ggplot(aes(x = AGE, y = GENERAL.VOTES)) +
            geom_point() +
            geom_smooth(formula = y ~ x, method = "lm") +
            labs(title="Comaprison of Age and General Votes",
            y = "No. of General Votes", x = " Age"))
    NA
    1. For 2nd Pair
    
    ggplotly(indian_election_df_winner %>% 
      ggplot(aes(x = CATEGORY, y = AGE, fill = CATEGORY)) +
      geom_point()+
        
      labs(title="Comaprison of Category and Age of Winning Candidates ", 
           y = "Age", x = "Category"))
    NA
    NA

    2. Describe the form, direction, and strength of the observed relationship. Include both qualitative and quantitative measures, as appropriate.

    Ans–> When examining a scatterplot and Boxplot , we have to be able to explain the relationship between the variables that we observe.

    The form, direction, and Strength of the connection, as well as the existence of any outliers, should always be included in a brief description of the association in a scatterplot.

    Form: Is the relationship of either linear or nonlinear. Here in our 1st case it is slighly showing negative linear relation as Age is increasing no. of votes are decreasing.

    Strength: Does it seem as though there is a strong, fairly strong, or weak association. In our case there is weak relationship.

    cor(indian_election_df_winner$AGE,indian_election_df_winner$GENERAL.VOTES)
    [1] -0.02191641

    Direction: It tells whether the relationship is positive or negative. In our case relationship is negative and weak.

    3. Explain what this relationship means in the context of the data?

    Ans–> The significance of the correlation coefficient for the variables indicates the direction of the relationship between the two. Positive relationships are denoted with a “plus” symbol, whereas bad relationships are denoted by a “minus” sign.

    Positive –> When two variables are positively correlated, they both tend to move in the same direction: If one grows, the other usually follows suit. One tends to diminish when the other does as well.

    Negative –> When two variables are negatively correlated, they often move in the opposite directions: if one grows, the other tends to drop, and vice versa.

    The form is refered to the whether relationship is linear or non linear.

    Linear–>A straight connection is referred to as being linear since it resembles a straight line.

    Curvilinear–> Because a curved connection resembles a curved line, it is referred to as being curvilinear.

    We exclusively work with correlation coefficients that measure linear relationships in this Value. Other correlation coefficients exist that quantify curved relationships, but they are advanced in nature.

    Perfect Relationship–>The coefficient of correlation is either +1.00 or -1.00 when two variables are linearly connected. Either favourably or negatively, it is claimed that they are precisely linearly connected.

    No Relationship–>Relationship: When there is absolutely no connection between two variables, their correlation coefficient is 0.00.

    For all these things we use coefficient of correlation. Predictions may be made with the use of correlations. We may expect that two variables will continue to correlate in the ahead if they have been shown to do so in the past. To forecast the value that the other variable will have in the future, we may utilise the value of one variable.

    4. Describe the variability that you observe in the plot and how that corresponds to the strength you calculated in no. 2 above.

    Variance–> The statistical assessment of the variation in numbers within a data collection is known as variance. In more detail, variance assesses how far apart each number in the collection is from the mean (average) and, consequently, from each other. The square root of the variance is the Standard Deviation.

    We can learn more about our data than what is often shown by conventional statistical summaries by using a scatterplot to visualise it. Bivariate data can be summarised using one of two fundamental methods: regression analysis or correlation analysis. Regression analysis describes how to leverage the relationship between the two components to forecast or control one variable using the other. The standard error of estimate and coefficient of determination, both equal to the square of the correlation r, are two indicators of how well a regression analysis performed. The former indicates the typical size of prediction errors, while the latter indicates the proportion of the Y variable’s variability that is “explained” by the X variable.

    Now, in our first scatter plot, we can observe that the majority of the data is present for both the variable x and y axis in the middle of the graph.

    According to strength of our data our scatter plot is weak in relationship. I must say it is negative in relationship.


      Tulaib Bin Ayyub (0789141)

      Univariate Analysis


      Numeric Variable : Postal Votes


    df_ind_elec <- read.csv("Indian_Election_2019.csv")
    df_ind_elec

    #Univariate #Numeric variable:

    Ques1. Create an appropriate plot to visualize the distribution of this variable.

    
    ggplotly(df_ind_elec %>% 
      ggplot(aes(POSTAL.VOTES))+
      geom_histogram(binwidth = 70, color = "darkblue")+
        labs(title = "DISTRIBUTION OF POSTAL VOTES", x = "Number Of Postal Votes", y = "Count"))
    NA

    Ques2. Consider any outliers present in the data. If present, specify the criteria used to identify them and provide a logical explanation for how you handled them.

    ggplotly(df_ind_elec %>% 
               ggplot(aes(y = POSTAL.VOTES))+
               geom_boxplot(fill = "skyblue"))

    Ans2. After looking at the generated boxplot, we can clearly see that there are multiple outliers. To handle the outliers we can impute them with median if they are close to median or we can impute them with any value closer to the outliers which is not an outlier.

    Ques3. Describe the shape and skewness of the distribution.

    mean(df_ind_elec$POSTAL.VOTES)
    [1] 990.7106

    Ans3. After finding the mean above and median in question 2, we can say that the shape and skewness of the distribution are unimodel and right skewed because most of the data are in left part.

    Ques4. Based on your answer to the previous question, decide if it is appropriate to apply a transformation to your data. If no, explain why not. If yes, name the transformation applied and visualize the transformed distribution.

    df_ind_elec <- df_ind_elec %>%
      mutate(sqrt_pst.vote = sqrt(POSTAL.VOTES))
    
    ggplotly(df_ind_elec %>% 
      ggplot(aes(sqrt_pst.vote))+
      geom_histogram(binwidth = 10, fill = "skyblue", color = "black")+
        labs(title = "DISTRIBUTION USING SQUARE ROOT TRANSFORMATION", x = "sqrt(POSTAL VOTES)", y = "Count"))

    Ans4. After using Log10 Transformation it is difficult to interpret the visualization because the data has too many zero values which gives us negative infinity. And after using square root transformation it is easy to interpret the distribution which is in a shape of unimodel and the distribution is right skewed.

    Ques5. Choose and calculate an appropriate measure of central tendency.

    mean(df_ind_elec$POSTAL.VOTES)
    [1] 990.7106

    Ques6. Explain why you chose this as your measure of central tendency. Provide supporting evidence for your choice.

    ggplotly(df_ind_elec %>% ggplot(aes(y = POSTAL.VOTES))+
      geom_boxplot(fill = "skyblue"))

    Ans6. Chose this because it is showing the average of postal votes which is very different in comparison to the median. In this boxplot we can see the median is low i.e., 316.00 and the mean was 990.7106 as we saw in previous answer.

    Ques7. Choose and calculate a measure of spread that is appropriate for your chosen measure of central tendency. Explain why you chose this as your measure of spread.

    sd(df_ind_elec$POSTAL.VOTES)
    [1] 1602.839

    Ans. To calculate measures of spread we can use minimum value, maximum value, standard deviation, variance, interquartile(IQR), etc. We are taking standard deviation and the value is high so the value in the data set are spread over a wide range.

      Categorical Variable : State


    Categorical variable:

    Ques1. Create an appropriate plot to visualize the distribution of counts for this variable.

    ggplotly(df_ind_elec %>% ggplot(aes(STATE))+
      geom_bar(fill = "skyblue", color = "black")+
        coord_flip()+
        labs(title = "DISTRIBUTION OF STATES", x = "States", y = "Count"))

    Ques2. Create an appropriate plot to visualize the distribution of proportions for this variable.

    df_ind_elec %>% 
      ggplot(aes(x = factor(1), fill = factor(STATE)))+
      geom_bar(width = 1)+
      coord_polar(theta = 'y', start = 0)+
      labs(title = "PROPORTIONS OF DIFFERENT STATES", x = "States")

    NA
    NA

    Ques3. Discuss any unusual observations for this variable?

    Ans3. Having too many value in this variable which is making it hard to interpret the visualization.

    Ques4. Discuss if there are too few/too many unique values?

    unique(df_ind_elec$STATE)
     [1] "Telangana"                 "Uttar Pradesh"            
     [3] "Maharashtra"               "Gujarat"                  
     [5] "Rajasthan"                 "Kerala"                   
     [7] "West Bengal"               "Uttarakhand"              
     [9] "Andhra Pradesh"            "Haryana"                  
    [11] "Punjab"                    "Jammu & Kashmir"          
    [13] "Andaman & Nicobar Islands" "Tamil Nadu"               
    [15] "Bihar"                     "Arunachal Pradesh"        
    [17] "Odisha"                    "Assam"                    
    [19] "Karnataka"                 "Madhya Pradesh"           
    [21] "Chhattisgarh"              "Chandigarh"               
    [23] "NCT OF Delhi"              "Jharkhand"                
    [25] "Dadra & Nagar Haveli"      "Daman & Diu"              
    [27] "Himachal Pradesh"          "Manipur"                  
    [29] "Lakshadweep"               "Mizoram"                  
    [31] "Nagaland"                  "Goa"                      
    [33] "Puducherry"                "Meghalaya"                
    [35] "Sikkim"                    "Tripura"                  

    Ans4. Yes there are too many unique values i.e., 36.


      Bivariate Analysis


      One pair of Numeric Variable : AGE and Postal Votes


      One pair of Numeric and Categorical Variable : AGE and Winner


    Ques1. Create an appropriate plot to visualize the relationship between the two variables.

    Ans1. 1. Plot using two numerical variables.

    df_ind_elec <- df_ind_elec %>% 
                    mutate(POSTAL.VOTES = POSTAL.VOTES/100)
    ggplotly(df_ind_elec %>% 
               ggplot(aes(x = AGE, y = POSTAL.VOTES))+
               geom_point(color = "skyblue")+
               geom_smooth(method = "gam", 
                           formula = y ~ s(x, bs = "cs")))
    Warning: Removed 245 rows containing non-finite values (stat_smooth).
    1. Plot using one numerical and one categorical variable.
    ggplotly(df_ind_elec %>%
      ggplot(aes(x = WINNER, y = AGE))+
      geom_point(color = "skyblue"))

    Ques2. Describe the form, direction, and strength of the observed relationship. Include both qualitative and quantitative measures, as appropriate.

    cor( df_ind_elec$AGE, df_ind_elec$POSTAL.VOTES, 
         use = "complete.obs")
    [1] 0.12936

    Ans2. Form tells if the relationship is linear or non-linear and in our case the form is showing linear correlation. Direction tells if the correlation is positive or negative and in our case it is showing positive correlation. Strength tells weather the correlation is weak strong or fairly strong and in our case the relation between variables is fairly strong i.e., 0.12936.

    Ques3. Explain what this relationship means in the context of the data.

    Ans3. This relationship means to understand and find the correlation between two variables. So that we can find the positive, negative, curvilinear relationship. We can say the relationship is perfect if the value lies between -1 to +1 and a no relationship when no relation is found so the correlation is 0. To find the relationship we use correlation coefficient.

    Ques4. Describe the variability that you observe in the plot and how that corresponds to the strength

    you calculated in #2 above.

    Ans4. By utilizing a scatter plot to visualize our data, we may discover more about it than what is frequently shown by traditional statistical summaries. One of the two primary techniques—correlation analysis or regression analysis—can be used to summarize bivariate data. Regression analysis explains how to take advantage of the connection between the two elements to predict or regulate one parameter using the other. Two measures of how well a regression analysis worked are the standard error of estimate and coefficient of determination, both equal to the square of the correlation r. Indicated by the latter is the percentage of the Y variable’s variability that can be “explained” by the X variable, the former indicating the average size of prediction mistakes. Scatter plot shows a rather good and fairly strong relationship with the quality of our data and it is a possibly positive relationship


      Alisha Mahajan(0802631)

      Univariate Analysis


      Numeric Variable : GENERAL VOTES


    ind_elec <- read.csv("Indian_election_2019.csv")
    

    1. Create an appropriate plot to visualize the distribution of this variable.

    
    ind_elec <- ind_elec %>%
      mutate(GENERAL.VOTES = GENERAL.VOTES/1000)
    
    
    ggplot(ind_elec, aes(x = GENERAL.VOTES))+
      geom_histogram( color = "BLUE", fill = "YELLOW") +
      labs(title="Distribution of general votes in 2019 election", 
           y = "Count", x = "No. of general votes") 

    In the above histogram, it can be seen that there is right skewed distribution where general votes lies mostly on left side.

    2.Consider any outliers present in the data. If present, specify the criteria used to identify them and provide a logical explanation for how you handled them.

    ggplotly(ind_elec %>% 
      ggplot(aes(y = GENERAL.VOTES)) +
      geom_boxplot(color = "Red", fill = "blue")+
      labs(title="Distribution of General votes in 2019 election", 
           x = "Count", y = "General Votes"))

    In above box plot, it can be seen that there are many outliers in this plot which can be calculated as:

    Interquartile (IQR) = Q3-Q1 = 485.81 - 21.03 = 464.78

    possible outliers: values > = Q3 + 1.5 * IQR (capping) and values < = Q1 - 1.5 * IQR (flooring)

    values > = 1182.98 and values < = -676.14

    So, according to this formula, there is no outliers in this plot. but in my analysis there are some outliers which falls between 485.81 and 1066.82.

    How to handel outliers:

    1. first way to handle these outliers is to simply delete it or remove it. But this is not an appropriate way.
    2. second way is to assign that value which is nearer value.
    3. And Third way is to find the mean, if it is nearby the values then we take that value.

    3. Describe the shape and skewness of the distribution?

    Ans: The shape of the distribution is unimodel as it has one hump and it can be clearly seen that there is right skewed distribution where general votes lies mostly on left side.

    4. Based on your answer to the previous question, decide if it is appropriate to apply a transformation to your data. If no, explain why not. If yes, name the transformation applied and visualize the transformed distribution.

     summary(ind_elec$GENERAL.VOTES)
        Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
       1.339   21.035  153.934  261.599  485.804 1066.824 
    summary(log10(ind_elec$GENERAL.VOTES))
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
     0.1268  1.3229  2.1873  2.0352  2.6865  3.0281 
    summary(sqrt(ind_elec$GENERAL.VOTES))
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1.157   4.586  12.407  13.621  22.041  32.662 
    ind_elec$log_gvote <- log10(ind_elec$GENERAL.VOTES)
    
    
    ggplotly(ind_elec %>% 
      ggplot(aes(x = log_gvote)) +
      geom_histogram(color = "yellow",fill = "red",bins = 20)+
      labs(title="Distribution of Log10(GENERAL VOTES) for Candidate", 
           y = "Count", x = "Log10(General Votes of Candidate)") )
    ind_elec$sqrt_gvotes = sqrt(ind_elec$GENERAL.VOTES)
    
    ggplotly(ind_elec %>% 
      ggplot(aes(x = sqrt_gvotes)) +
      geom_histogram(color = "yellow",fill = "red",bins = 20)+
      labs(title="Distribution of SQRT(GENERAL VOTES) for Candidate", 
           y = "Count", x = "SQRT(General Votes of Candidate)") )
    NA

    After comparing above 3 plots, 1 in question 2nd and 2 in question 4th i.e. log10 and sqrt, it can be decided that we can take Ist plot which is symmetrical rather that other two plots that are not symmetrical(forming 2 humps.)

    5 . Choose and calculate an appropriate measure of central tendency.

    Ans: Central tendency: The statistical measure that designates one value as being representative of a whole distribution is known as central tendency. [2] The complete set of data will be accurately described. It is the single value that best characterizes or encapsulates the information gathered.

    Mean, median and mode are three ways that are used to measure central tendency.

    median_value <- median(ind_elec$GENERAL.VOTES)
    median_value
    [1] 153.934
    mean_value <- mean(ind_elec$GENERAL.VOTES)
    mean_value
    [1] 261.5991

    6. Explain why you chose this as your measure of central tendency. Provide supporting evidence for your choice .

    Ans: After analyzing central tendency for mean and median of variable general votes, I take mean as the measure for central tendency because it it more accurate than median and also our data is mostly on left side and also we are calculated average of general votes. so, mean is best suited for this variable.

    7. Choose and calculate a measure of spread that is appropriate for your chosen measure of central tendency. Explain why you chose this as your measure of spread.

    Ans: We can calculate measure of spread in many ways like Range, IQR, Variance, Mean deviation, Standard deviation. but here I am calculating variance for general votes:

    var(ind_elec$GENERAL.VOTES)
    [1] 65020.2

    The average squared deviation from the mean, also known as variance, gives us the average dispersion from the mean for a given set of data. However, if an outlier is present, the value returned after squaring the deviation from the mean would be excessively large, which immediately leads us to the conclusion that an outlier is present in the data set. When you calculate the variance, you’ll see that the result is abnormally high in the big picture. We basically take the square root of these numbers to restore them to their normal value and give us a number that is much more typical in order to account for this.


      Categorical Variable : EDUCATION


    1.Create an appropriate plot to visualize the distribution of counts for this variable.

    ggplotly(ind_elec %>% 
      ggplot(aes(x = EDUCATION)) +
      geom_bar(color = "bLUE",fill = "PINK")+
      labs(title="Count of Education Candidate", 
           y = "Count", x = "Education") )

    2. Create an appropriate plot to visualize the distribution of proportions for this variable.

    
    ind_elec %>% 
      ggplot(aes(x = factor(1), fill = factor(EDUCATION)))+
      geom_bar( width = 1)+
      coord_polar(theta = 'y', start = 0)+
      labs(title="Proportions of Education of Candidate", 
           y = "Count", x = "Education") 

    NA
    NA
    NA

    3. Discuss any unusual observations for this variable.

    Ans: There are some unusual observations of Eductaion categorical variable like

    1. In some observations there are duplicate values.
    2. In some of the cases there are missing values.
    3. In this variable some values are “Not Available”

    4. Discuss if there are too few/too many unique values?

    Ans:There are total 13 unique values, we have in this categorical variable.

    unique(ind_elec$EDUCATION)
     [1] "12th Pass"             "Post Graduate"         ""                     
     [4] "Doctorate"             "Graduate"              "Others"               
     [7] "10th Pass"             "8th Pass"              "Graduate Professional"
    [10] "Literate"              "Illiterate"            "5th Pass"             
    [13] "Not Available"         "Post Graduate\n"      

      Bivariate Analysis


      One pair of Numeric Variable : AGE and Total Votes


      One pair of Numeric and Categorical Variable : AGE and STATE


    1. Create an appropriate plot to visualize the relationship between the two variables.

    
    ind_elc <- ind_elec %>% 
                mutate(TOTAL.VOTES=TOTAL.VOTES/1000)
    
    ggplotly(ind_elc%>% 
            ggplot(aes(x = AGE, y = TOTAL.VOTES, color = CATEGORY)) +
            geom_point() +
            geom_smooth(formula = y ~ x, method = "lm") +
            labs(title="Comparison of Age and Total Votes",
            y = "No. of Total Votes", x = " Age"))
    Warning: Removed 245 rows containing non-finite values (stat_smooth).
    1. For 2nd pair
    
    ggplotly(ind_elc %>% 
      ggplot(aes(x = AGE, y = STATE, fill = STATE)) +
      geom_point()+
        
      labs(title="Comparison of State and Age of Candidates ", 
           y = "State", x = "Age"))
    NA
    NA

    2. Describe the form, direction, and strength of the observed relationship. Include both qualitative

    and quantitative measures, as appropriate.

    Ans–> In a scatterplot, a quick summary of the link should always include the form, direction, and strength of the connection as well as the presence of any outliers.

    Form: Is the relationship of either linear or nonlinear. Here in our 1st case it is slighly showing positive linear relation as Age is increasing no. of Total votes are Increasing.

    Strength : It tells us how strong is relation between the variables, either weak, strong or fairly strong. But in this case Our relation is fairly strong and positive. Here below we are calculating correlation coefficient within two variables.

    
    cor(ind_elc$AGE, ind_elc$TOTAL.VOTES, use = "complete.obs")
    [1] 0.2085995

    Direction: It tells whether the relationship is positive or negative. In our case relationship is Positive and fairly strong.

    3 Explain what this relationship means in the context of the data.

    Ans–> Understanding and determining the correlation between two variables is what this connection refers to. in order to identify the curvilinear, positive, and negative relationships. If the value is between -1 and +1, then the relationship is perfect; otherwise, there is no association, and the correlation is 0. We utilize the correlation coefficient to discover the relationship. In our case correlation coefficient is positive i.e + 0.208

    4 Describe the variability that you observe in the plot and how that corresponds to the strength

    you calculated in #2 above.

    Ans–> The Variance is the numerical measure of how thew data is spread across the mean. The R language’s var() function calculates a vector’s sample variance. It serves as a gauge for how much a value deviates from the mean. The square root of the variance is the standard deviation.

    Two measures of how well a regression analysis worked are the standard error of estimate and coefficient of determination, both equal to the square of the correlation r. Indicated by the latter is the percentage of the Y variable’s variability that can be “explained” by the X variable, the former indicating the average size of prediction mistakes.

    Now in our first Scatter plot most of the data is present in the bottom of the graph, which means mostly values of total votes are less.

    According to strength of our data our scatter plot is fairly strong in relationship. I must say it is positive relation.

    LS0tDQp0aXRsZTogIkRBQjUwMS1Qcm9qZWN0LTItIEdyb3VwLTMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQo8aHRtbD4NCjxoZWFkPg0KPHRpdGxlPiA8L3RpdGxlPg0KPGJvZHk+IDxoND48Yj4gPEZPTlQgQ09MT1I9IlNLWUJMVUUiPlZpc2hhbnQgQmhhdGlhKDA3OTg1NjcpLCBUdWxhaWIgQmluIEF5eXViKDA3ODkxNDEpLCBBbGlzaGEgTWFoYWphbigwODAyNjMxKTwvRk9OVCBDT0xPUj48L2I+PC9oND4NCg0KPHA+IDxiPldlLFZpc2hhbnQgQmhhdGlhLCBUdWxhaWIgQmluIEF5eXViLCBhbmQgQWxpc2hhIE1haGFqYW4gaGVyZWJ5IHN0YXRlIHRoYXQgd2UgaGF2ZSBub3QgY29tbXVuaWNhdGVkIHdpdGggb3IgZ2FpbmVkIGluZm9ybWF0aW9uIGluIGFueSB3YXkgZnJvbSBhbnkgcGVyc29uIG9yIHJlc291cmNlIHRoYXQgd291bGQgdmlvbGF0ZSB0aGUgQ29sbGVnZeKAmXMgYWNhZGVtaWMgaW50ZWdyaXR5IHBvbGljaWVzLCBhbmQgdGhhdCBhbGwgd29yayBwcmVzZW50ZWQgaXMgb3VyIG93bi4gSW4gYWRkaXRpb24sIHdlIGFsc28gYWdyZWUgbm90IHRvIHNoYXJlIG91ciB3b3JrIGluIGFueSB3YXksIGJlZm9yZSBvciBhZnRlciBzdWJtaXNzaW9uLCB0aGF0IHdvdWxkIHZpb2xhdGUgdGhlIENvbGxlZ2XigJlzIGFjYWRlbWljIGludGVncml0eSBwb2xpY2llcy48L2I+PC9wPg0KDQo8cD5SIHZlcnNpb24gdXNlZC0gUiB2ZXJzaW9uIDQuMi4xICgyMDIyLTA2LTIzIHVjcnQpICAgICA8L3A+DQo8cD5SU3R1ZGlvIHVzZWQtIDIwMjIuMDcuMSB2ZXJzaW9uICAgICAgPC9wPg0KDQpMaXN0IG9mIFIgcGFja2FnZXMgdXNlZC0gdGlkeXZlcnNlLCBoZXJlLCBwbG90bHksIGdncGxvdDIuDQoNCjxoNT4gPGI+IExpYnJhcnkgSW1wb3J0ZWQgYW5kIHRoZWlyIHZlcnNpb25zPC9iPjwvaDU+DQoNCjxsaT50aWR5dmVyc2UgOiAxLjMuMiA8L2xpPg0KPGxpPmhlcmUgOiAxLjAuMSA8L2xpPg0KPGxpPnBsb3RseSA6IDQuMTAuMCA8L2xpPg0KPGxpPmdncGxvdDIgOiAzLjMuNjwvbGk+DQoNCjxGT05UIFNJWkU9MTQ+PEZPTlQgQ09MT1I9IlNLWUJMVUUiPjxiPjxoMz4gQ29udHJpYnV0aW9uIG9mIGVhY2ggbWVtYmVyOjwvaDM+PC9iPjwvRk9OVCBDT0xPUj48L0ZPTlQgU0laRT4NCg0KPFA+PGg0Pjx1bD48Yj5WaXNoYW50IEJoYXRpYSgwNzk4NTY3KTwvYj48L3VsPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIEhpc3RvZ3JhbSBwbG90IGRpc3BsYXlpbmcgZGlzdHJpYnV0aW9uIGFib3V0IGEgc2luZ2xlIG51bWVyaWNhbCB2YXJpYWJsZSBpLmUgQWdlIG9mIFdpbm5pbmcgQ2FuZGlkYXRlcy48L0ZPTlQgU0laRT48L2xpPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIEJveCBwbG90IGRpc3BsYXlpbmcgaW5mb3JtYXRpb24gYWJvdXQgb3V0bGllcnMgb2YgYWJvdmUgbnVtZXJpY2FsIHZhcmlhYmxlLjwvRk9OVCBTSVpFPjwvbGk+PGxpPjxGT05UIFNJWkU9Mz5QcmVwYXJlZCBvbmUgQmFyIGNoYXJ0IGRpc3BsYXlpbmcgY291bnQgaW5mb3JtYXRpb24gYWJvdXQgb25lIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGkuZSBDYXRlZ29yeSBvZiB3aW5uaW5nIGNhbmRpZGF0ZXMuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBQaWUgY2hhcnQgZGlzcGxheWluZyBwcm9wb3J0aW9ucyBpbmZvcm1hdGlvbiBhYm91dCBhYm92ZSBjYXRlZ29yaWNhbCB2YXJpYWJsZS48L0ZPTlQgU0laRT48L2xpPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIFNjYXR0ZXIgUGxvdCBkaXNwbGF5aW5nICBpbmZvcm1hdGlvbiBhYm91dCBwYWlyIG9mIE51bWVyaWNhbCB2YXJpYWJsZSBBZ2UgYW5kIEdlbmVyYWwgVm90ZXMuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBTY2F0dGVyIFBsb3QgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCBwYWlyIG9mIG9uZSBOdW1lcmljYWwgdmFyaWFibGUgQWdlIGFuZCBvbmUgY2F0ZWdvcmljYWwgdmFyaWFibGUgQ2F0ZWdvcnkuPC9GT05UIFNJWkU+PC9saT48YnI+DQoNCg0KPFA+PGg0Pjx1bD48Yj5UdWxhaWIgQmluIEF5eXViKDA3ODkxNDEpPC9iPjwvdWw+PGxpPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIEhpc3RvZ3JhbSBwbG90IGRpc3BsYXlpbmcgZGlzdHJpYnV0aW9uIGFib3V0IGEgc2luZ2xlIG51bWVyaWNhbCB2YXJpYWJsZSBpLmUgUG9zdGFsIFZvdGVzLjwvRk9OVCBTSVpFPjwvbGk+PGxpPjxGT05UIFNJWkU9Mz5QcmVwYXJlZCBvbmUgQm94IHBsb3QgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCBvdXRsaWVycyBvZiBhYm92ZSBudW1lcmljYWwgdmFyaWFibGUuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBCYXIgY2hhcnQgZGlzcGxheWluZyBjb3VudCBpbmZvcm1hdGlvbiBhYm91dCBvbmUgY2F0ZWdvcmljYWwgdmFyaWFibGUgaS5lIFN0YXRlLjwvRk9OVCBTSVpFPjwvbGk+PGxpPjxGT05UIFNJWkU9Mz5QcmVwYXJlZCBvbmUgUGllIGNoYXJ0IGRpc3BsYXlpbmcgcHJvcG9ydGlvbnMgaW5mb3JtYXRpb24gYWJvdXQgYWJvdmUgY2F0ZWdvcmljYWwgdmFyaWFibGUuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBTY2F0dGVyIFBsb3QgZGlzcGxheWluZyAgaW5mb3JtYXRpb24gYWJvdXQgcGFpciBvZiBOdW1lcmljYWwgdmFyaWFibGUgQWdlIGFuZCBQb3N0YWwgVm90ZXMuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBTY2F0dGVyIFBsb3QgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCBwYWlyIG9mIG9uZSBOdW1lcmljYWwgdmFyaWFibGUgQWdlIGFuZCBvbmUgY2F0ZWdvcmljYWwgdmFyaWFibGUgV2lubmVyPC9GT05UIFNJWkU+PC9saT48YnI+DQoNCg0KPFA+PGg0Pjx1bD48Yj5BbGlzaGEgTWFoYWphbigwODAyNjMxKTwvYj48L3VsPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIEhpc3RvZ3JhbSBwbG90IGRpc3BsYXlpbmcgZGlzdHJpYnV0aW9uIGFib3V0IGEgc2luZ2xlIG51bWVyaWNhbCB2YXJpYWJsZSBpLmUgR2VuZXJhbCBWb3Rlcy48L0ZPTlQgU0laRT48L2xpPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIEJveCBwbG90IGRpc3BsYXlpbmcgaW5mb3JtYXRpb24gYWJvdXQgb3V0bGllcnMgb2YgYWJvdmUgbnVtZXJpY2FsIHZhcmlhYmxlLjwvRk9OVCBTSVpFPjwvbGk+PGxpPjxGT05UIFNJWkU9Mz5QcmVwYXJlZCBvbmUgQmFyIGNoYXJ0IGRpc3BsYXlpbmcgY291bnQgaW5mb3JtYXRpb24gYWJvdXQgb25lIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGkuZSBFZHVjYXRpb24gb2YgY2FuZGlkYXRlcy48L0ZPTlQgU0laRT48L2xpPjxsaT48Rk9OVCBTSVpFPTM+UHJlcGFyZWQgb25lIFBpZSBjaGFydCBkaXNwbGF5aW5nIHByb3BvcnRpb25zIGluZm9ybWF0aW9uIGFib3V0IGFib3ZlIGNhdGVnb3JpY2FsIHZhcmlhYmxlLjwvRk9OVCBTSVpFPjwvbGk+PGxpPjxGT05UIFNJWkU9Mz5QcmVwYXJlZCBvbmUgU2NhdHRlciBQbG90IGRpc3BsYXlpbmcgIGluZm9ybWF0aW9uIGFib3V0IHBhaXIgb2YgTnVtZXJpY2FsIHZhcmlhYmxlIEFnZSBhbmQgVG90YWwgVm90ZXMuPC9GT05UIFNJWkU+PC9saT48bGk+PEZPTlQgU0laRT0zPlByZXBhcmVkIG9uZSBTY2F0dGVyIFBsb3QgZGlzcGxheWluZyBpbmZvcm1hdGlvbiBhYm91dCBwYWlyIG9mIG9uZSBOdW1lcmljYWwgdmFyaWFibGUgQWdlIGFuZCBvbmUgY2F0ZWdvcmljYWwgdmFyaWFibGUgU3RhdGU8L0ZPTlQgU0laRT48L2xpPjxicj4NCg0KPGgyPjxGT05UIENPTE9SPSJTS1lCTFVFIj4gRGF0YXNldDogSW5kaWFuIEVsZWN0aW9uIDIwMTk8L0ZPTlQgQ09MT1I+PC9oMj4NCjxoND48cD48dWw+IFNvdXJjZTogPC91bD4gPGEgaHJlZj1odHRwczovL3d3dy5rYWdnbGUuY29tL2NvZGUvcGFyYW1hcnRoYXNlbmd1cHRhL2VkYS1wbG90bHktcHJlZGljdGlvbi1pbmRpYW4tZWxlY3Rpb25zLTIwMTk+IGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vY29kZS9wYXJhbWFydGhhc2VuZ3VwdGEvZWRhLXBsb3RseS1wcmVkaWN0aW9uLWluZGlhbi1lbGVjdGlvbnMtMjAxOTwvYT48YnI+DQo8YnI+DQo8aDU+IDxiPiBEYXRhdHlwZXMgYW5kIFZhcmlhYmxlcyA8L2I+PC9oNT4NCjxsaT4gDQpTVEFURS0tLS1jaHIgdHlwZQ0KPC9saT4NCjxsaT4gIA0KQ09OU1RJVFVFTkNZLS0tLWNociB0eXBlDQo8L2xpPg0KPGxpPg0KTkFNRS0tLS1jaHIgdHlwZQ0KPC9saT4NCjxsaT4NCldJTk5FUi0tLS1pbnQgdHlwZQ0KPC9saT4NCjxsaT4NClBBUlRZLS0tLWNociB0eXBlDQo8L2xpPg0KPGxpPg0KU1lNQk9MLS0tLWNociB0eXBlDQo8L2xpPg0KPGxpPg0KR0VOREVSLS0tLWNociB0eXBlDQo8L2xpPg0KPGxpPg0KQ1JJTUlOQUwuQ0FTRVMtLS0tY2hyIHR5cGUNCjwvbGk+DQo8bGk+DQpBR0UtLS0taW50IHR5cGUNCjwvbGk+DQo8bGk+DQpDQVRFR09SWS0tLS1jaHIgdHlwZQ0KPC9saT4NCjxsaT4NCkVEVUNBVElPTi0tLS1jaHIgdHlwZQ0KPC9saT4NCjxsaT4NCkFTRVRTLS0tLWNociB0eXBlDQo8L2xpPg0KPGxpPg0KTElBQklMSVRJRVMtLS0tY2hyIHR5cGUNCjwvbGk+DQo8bGk+DQpHRU5FUkFMLlZPVEVTLS0tLWludCB0eXBlDQo8L2xpPg0KPGxpPg0KUE9TVEFMLlZPVEVTLS0tLWludCB0eXBlDQo8L2xpPg0KPGxpPg0KVE9UQUwuVk9URVMtLS0taW50IHR5cGUNCjwvbGk+DQo8bGk+DQpPVkVSLlRPVEFMLkVMRUNUT1JTLklOLkNPTlNUSVRVRU5DWeKGkiBudW0gdHlwZQ0KPC9saT4NCjxsaT4NCk9WRVIuVE9UQUwuVk9URVMuUE9MTEVELi5JTi5DT05TVElUVUVOQ1nihpIgbnVtIHR5cGUNCjwvbGk+DQo8bGk+DQpUT1RBTC5FTEVDVE9SUy0tLS1pbnQgdHlwZQ0KPC9saT4NCg0KPHA+ICAgPC9wPg0KPGJyPg0KDQo8aDQ+DQoNCg0KYGBge3J9DQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQ0KbGlicmFyeSgiaGVyZSIpDQpsaWJyYXJ5KCJwbG90bHkiKQ0KbGlicmFyeSgiZ2dwbG90MiIpDQpsaWJyYXJ5KCJwbG90cml4IikNCmBgYA0KDQoNCmBgYHtyfQ0Kc2V0d2QoIkM6XFxGIERyaXZlXFxCQXNpYyBzdGF0cyBEQUIgNTAxXFxQcm9qZWN0IDIiKQ0KYGBgDQoNCg0KPFA+PGgzPjx1bD48Yj5WaXNoYW50IEJoYXRpYSgwNzk4NTY3KTwvYj48L3VsPjxicj4NCjxQPjxoNT48dWw+PHU+VW5pdmFyaWF0ZSBBbmFseXNpczwvdT48L3VsPjxicj4NCg0KPFA+PGg1Pjx1bD5OdW1lcmljIFZhcmlhYmxlIDogPGI+QUdFPC9iPjwvdWw+PGJyPg0KDQoNCg0KYGBge3J9DQppbmRpYW5fZWxlY3Rpb25fZGYgPC0gcmVhZC5jc3YoIkluZGlhbl9FbGVjdGlvbl8yMDE5LmNzdiIpIA0KDQojaW5kaWFuX2VsZWN0aW9uX2RmDQoNCmBgYA0KDQoNCiMgMS4gQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhpcyB2YXJpYWJsZS4NCg0KYGBge3J9DQppbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyIDwtIGluZGlhbl9lbGVjdGlvbl9kZiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXSU5ORVIgPT0gMSkNCg0KIyBoZXJlIHdlIGFyZSBmaWx0ZXJpbmcgb3V0IGRhdGEgb25seSBvZiB3aW5uaW5nIGNhbmRpZGF0ZXMgb2YgSW5kaWFuIEVsZWN0aW9uIDIwMTkNCmBgYA0KDQoNCmBgYHtyfQ0KDQpnZ3Bsb3RseShpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gQUdFKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDMsY29sb3IgPSAieWVsbG93IixmaWxsID0gInJlZCIpKw0KICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgQWdlcyBmb3IgV2lubmluZyBDYW5kaWRhdGUiLCANCiAgICAgICB5ID0gIkNvdW50IiwgeCA9ICJBZ2Ugb2YgV2lubmluZyBDYW5kaWRhdGUiKSApDQoNCmBgYA0KDQpJbiBBYm92ZSBIaXN0b2dyYW0gcGxvdCB3ZSBjYW4gc2F5IHRoYXQgdGhlcmUgYXJlIG1hbnkgd2lubmluZyBjYW5kaWRhdGVzIGluIEluZGlhbiBFbGVjdGlvbiAyMDE5IG1vc3Qgb2YgdGhlIGFnZXMgYXJlIGxpZXMgYmV0d2VlbiA0NS02OS4NCg0KDQoNCiMgMi4gQ29uc2lkZXIgYW55IG91dGxpZXJzIHByZXNlbnQgaW4gdGhlIGRhdGEuIElmIHByZXNlbnQsIHNwZWNpZnkgdGhlIGNyaXRlcmlhIHVzZWQgdG8gaWRlbnRpZnkgdGhlbSBhbmQgcHJvdmlkZSBhIGxvZ2ljYWwgZXhwbGFuYXRpb24gZm9yIGhvdyB5b3UgaGFuZGxlZCB0aGVtLg0KDQoNCmBgYHtyfQ0KZ2dwbG90bHkoaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciAlPiUgDQogIGdncGxvdChhZXMoeSA9IEFHRSkpICsNCiAgZ2VvbV9ib3hwbG90KGNvbG9yID0gIlJlZCIsIGZpbGwgPSAiY3lhbiIpKw0KICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgQWdlcyBmb3IgV2lubmluZyBDYW5kaWRhdGUiLCANCiAgICAgICB4ID0gIkNvdW50IiwgeSA9ICJBZ2Ugb2YgV2lubmluZyBDYW5kaWRhdGUiKSkNCg0KDQoNCmBgYA0KDQpJbiBBYm92ZSBib3ggcGxvdCB3ZSBjYW4gY2xlYXJseSBzZWUgdGhhdCBNZWRpYW4gb2Ygd2lubmluZyBjYW5kaWRhdGVzIG9mIEluZGlhbiBFbGVjdGlvbiAyMDE5IGlzIDU1LCBhbmQgbW9zdCBvZiB0aGUgZGF0YSBsaWVzIGJldHdlZW4gNDctNjMgYWdlLiANCg0KVGhlcmUgYXJlIG1hbnkgd2F5cyB0byBmaW5kIE91dGxpZXJzIGluIGFib3ZlIGJveHBsb3QgYnV0IHRoZSBhY2N1cmF0ZSB3YXkgaXM6DQoNCjEuIEZpcnN0IHdlIGhhdmUgdG8gZmluZCB0aGUgZGlzdGFuY2UgYmV0d2VlbiBGaXJzdCBRdWFydGlsZSAoUTEpIGFuZCBUaGlyZCBRdWFydGlsZSAoUTMpLCB3aGljaCBpcyBjYWxsZWQgSW50ZXJxdWFydGlsZSAoSVFSKQ0KDQoyLiBBbnl0aGluZyB3aGljaCBpcyBiZXlvbmQgUTMgKyAxLjUgdGltZXMgdGhlIElRUiBhbmQgYW55dGhpbmcgd2hpY2ggaXMgbGVzcyB0aGFuIFExIC0gMS41IHRpbWVzIHRoZSBJUVIgZ2l2ZXMgdGhlIHBvc3NpYmxlIG91dGxpZXJzLlRoZXNlIGFyZSB0aG9zZSBvYnNlcnZhdGlvbnMgd2hpY2ggYXJlIGF3YXkgZnJvbSBib3guDQoNCjMuTW9zdCBQcm9iYWJsZSBvdXRsaWVycyBhcmUgdGhvc2UgdmFsdWVzIHRoYXQgYXJlIG1vcmUgdGhhbiBvciBsZXNzIHRoYW4gYWJvdmUgc3RhdGVtZW50Lg0KDQpGb3IgRXhhbXBsZSBpbiBvdXIgYWJvdmUgQm94UGxvdDotDQpRMSA9IDQ3DQpRMyA9IDYzDQpJUVIgPSBRMy1RMSA9IDE2DQoNCnBvc3NpYmxlIG91dGxpZXJzIGFyZSANCnZhbHVlcyA+ID0gUTMgKyAxLjUgKiBJUVIgY2FsbGVkIGNhcHBpbmcgYW5kIHZhbHVlcyA8ID0gUTEgLSAxLjUgKiBJUVIgY2FsbGluZyBmbG9vcmluZw0KDQpWYWx1ZXMgPiA9IDg3IChjYXBwaW5nKQ0KdmFsdWVzIDwgPSAyMyAoZmxvb3JpbmcpDQoNCkFjY29yZGluZyB0byB0aGlzIGZvcm11bGEgYW5kIGFmdGVyIHN0dWR5aW5nIGFib3ZlIGhpc3RvZ3JhbSBwbG90IHdlIGNhbiBzYXkgdGhhdCB3ZSBoYXZlIG9uZSBvdXRsaWVyIHRoYXQgaXMgODcgYW5kIGl0J3MgY291bnQgaXMgMS4NCg0KVGhlcmUgYXJlIG1hbnkgd2F5cyB0byBoYW5kbGUgb3V0bGllcnMuDQoNCkZpcnN0IGlzIHdlIGNhbiByZW1vdmUgdGhhdCByZWNvcmQuQnV0IGl0IGlzIG5vdCByZWNvbW1lbmRlZC4gDQoNClNlY29uZCB3YXkgaXMgaWYgdGhlcmUgYXJlIHNvIG1hbnkgb3V0bGllcnMgdmFsdWVzIHdlIGNhbiBhc3NpZ24gdGhlIHZhbHVlIG5lYXJlciB0byB0aGF0IG91dGxpZXIuIGZvciBleGFtcGxlIGlmIHZhbHVlcyBhcmUgZ3JlYXRlciB0aGFuIDk5IHBlcmNlbnRpbGUgdGhlbiB3ZSBjYW4gYXNzaWduIHRoZSA5OXRoIHBlcmNlbnRpbGUgdmFsdWUsIGFuZCBpZiB2YWx1ZSBpcyBsZXNzIHRoYW4gMSBwZXJjZW50aWxlIHRoZW4gd2UgY2FuIGFzc2lnbiB0aGUgMXN0IHBlcmNlbnRpbGUgdmFsdWUgdG8gdGhhdCBvdXRsaWVyLg0KDQpUaGlyZCB3YXkgaXMgYXNzaWduIHRoYXQgdmFsdWUgd2hpY2ggaXMgbmVhcmVyIHRvIHRoZSBtZWRpYW4gYW5kIG91dGxpZXIuDQoNCg0KIyAzLiBEZXNjcmliZSB0aGUgc2hhcGUgYW5kIHNrZXduZXNzIG9mIHRoZSBkaXN0cmlidXRpb24NCg0KQW5zLS0+IEluIG91ciAxc3QgcXVlc3Rpb24gd2UgbWFrZSBoaXN0b2dyYW0gcGxvdC4gVGhlIHNoYXBlIG9mIEhpc3RvZ3JhbSBpcyBzb21laG93IHN5bW1ldHJ5IGFuZCBiZWxsIHNoYXBlZC4gDQoNCg0KIyA0LiBCYXNlZCBvbiB5b3VyIGFuc3dlciB0byB0aGUgcHJldmlvdXMgcXVlc3Rpb24sIGRlY2lkZSBpZiBpdCBpcyBhcHByb3ByaWF0ZSB0byBhcHBseSBhIHRyYW5zZm9ybWF0aW9uIHRvIHlvdXIgZGF0YS4gSWYgbm8sIGV4cGxhaW4gd2h5IG5vdC4gSWYgeWVzLCBuYW1lIHRoZSB0cmFuc2Zvcm1hdGlvbiBhcHBsaWVkIGFuZCB2aXN1YWxpemUgdGhlIHRyYW5zZm9ybWVkIGRpc3RyaWJ1dGlvbi4NCg0KDQpgYGB7cn0NCnN1bW1hcnkoaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciRBR0UpDQpzdW1tYXJ5KGxvZzEwKGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIkQUdFKSkNCnN1bW1hcnkoc3FydChpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyJEFHRSkpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciRsb2dfYWdlIDwtIGxvZzEwKGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIkQUdFKQ0KDQpnZ3Bsb3RseShpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbG9nX2FnZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3IgPSAieWVsbG93IixmaWxsID0gInJlZCIsYmlucyA9IDIwKSsNCiAgbGFicyh0aXRsZT0iRGlzdHJpYnV0aW9uIG9mIExvZzEwKEFnZXMpIGZvciBXaW5uaW5nIENhbmRpZGF0ZSIsIA0KICAgICAgIHkgPSAiQ291bnQiLCB4ID0gIkxvZzEwKEFnZSBvZiBXaW5uaW5nIENhbmRpZGF0ZSkiKSApDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQppbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyJHNxcnRfYWdlIDwtIHNxcnQoaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciRBR0UpDQoNCmdncGxvdGx5KGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzcXJ0X2FnZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3IgPSAieWVsbG93IixmaWxsID0gInJlZCIsYmlucyA9IDIwKSsNCiAgbGFicyh0aXRsZT0iRGlzdHJpYnV0aW9uIG9mIFNRUlQoQWdlcykgZm9yIFdpbm5pbmcgQ2FuZGlkYXRlIiwNCiAgICAgICB5ID0gIkNvdW50IiwgeCA9ICJTUVJUKEFnZSBvZiBXaW5uaW5nIENhbmRpZGF0ZSkiKSApDQoNCmBgYA0KDQoNCkJ5IGNvbXBhcmluZyBhYm92ZSB0aHJlZSBoaXN0b2dyYW1zIG9uZSBmcm9tIDFzdCBxdWVzdGlvbiBhbmQgb3RoZXIgdHdvIGFyZSBmcm9tIExvZzEwIGFuZCBTUVJULCB3ZSBjYW4gc2F5IHRoYXQgdGhlcmUgaXMgbm8gbmVlZCBvZiB0cmFuc2Zvcm1hdGlvbiBvZiBvdXIgb3JpZ2luYWwgZGF0YSBhcyB0aGUgZGlzdHJpYnV0aW9uIGlzIHN5bW1ldHJ5IGFuZCBiZWxsIHNoYXBlZCBpbiBvdXIgb3JpZ2luYWwgaGlzdG9ncmFtLiANCg0KDQoNCg0KIyA1LiBDaG9vc2UgYW5kIGNhbGN1bGF0ZSBhbiBhcHByb3ByaWF0ZSBtZWFzdXJlIG9mIGNlbnRyYWwgdGVuZGVuY3kuDQpBbnMtLT4gVGhlIHdvcmQgImNlbnRyYWwgdGVuZGFuY3kiIGlzIGZhaXJseSBjb21tb24gaW4gc3RhdGlzdGljcy4gSXQncyBhIHRlY2huaXF1ZSB0byBleHBsYWluIGhvdyB5b3VyIGRhdGEgYXJlIGRpc3RyaWJ1dGVkLiBXaGlsZSBjZW50cmFsIHRlbmRhbmN5IGRvZXMgbm90IHByb3ZpZGUgeW91IHdpdGggdGhlIGZpbmUgZGV0YWlscyBvZiB5b3VyIGRhdGEsIGl0IGRvZXMgcHJvdmlkZSB5b3Ugd2l0aCBhIGdlbmVyYWwgbm90aW9uIG9mIGhvdyB5b3VyIGRhdGEgYXJlIGRpc3RyaWJ1dGVkLg0KDQpUaGUgbWVhbiwgbWVkaWFuLCBhbmQgbW9kZSBhcmUgdGhlIHRocmVlIG1vc3Qgd2lkZWx5IHVzZWQgcGFyYW1ldGVycyBvZiBjZW50cmFsIHRlbmRlbmN5LiBUaGUgbWVkaWFuIG9mIGFuIG9yZGVyZWQgZGF0YXNldCBpcyB0aGUgdmFsdWUgaW4gdGhlIGNlbnRyZSwgd2hlcmVhcyB0aGUgbWVhbiBvciBhdmVyYWdlIGlzIGVxdWFsIHRvIHRoZSBzdW0gb2YgYWxsIHRoZSB2YWx1ZXMgaW4gdGhlIGRhdGEgc2V0IGRpdmlkZWQgYnkgdGhlIG51bWJlciBvZiB2YWx1ZXMgaW4gdGhlIGRhdGEgc2V0LiBPbiB0aGUgb3RoZXIgc2lkZSwgbW9kZSBzaG93cyB5b3UgdGhlIGRhdGFzZXQncyBtb3N0IHJlcGVhdGFibGUgdmFsdWUuDQpTbyBpbiBvdXIgY2FzZSB3ZSBhcmUgdXNpbmcgbWVhbiBhcyBjZW50cmFsIHRlbmRlbmN5LiANCg0KYGBge3J9DQptZWFuKGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIkQUdFKQ0KDQpgYGANCg0KIyA2LiBFeHBsYWluIHdoeSB5b3UgY2hvc2UgdGhpcyBhcyB5b3VyIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gUHJvdmlkZSBzdXBwb3J0aW5nIGV2aWRlbmNlIGZvciB5b3VyIGNob2ljZS4NCg0KQmVjYXVzZSBhZ2UgaXMgYW4gaXNzdWUgYW5kIHdlIG5lZWQgdG8ga25vdyB0aGUgYXZlcmFnZSBhZ2Ugb2YgdGhlIGNhbmRpZGF0ZXMgd2hvIHdvdWxkIHdpbiB0aGUgMjAxOSBJbmRpYW4gRWxlY3Rpb24sIHdlIGhhdmUgY2hvc2VuICJNZWFuIiBhcyB0aGUgY2VudHJhbCB0ZW5kZW5jeS4gVGhlIHZpY3RvcmlvdXMgY2FuZGlkYXRlcycgYXZlcmFnZSBhZ2UgaXMgbm93IDU0LjQ0Lg0KU2luY2UgdGhlIG1lYW4gYW5kIG1lZGlhbiB2YWx1ZXMgaW4gdGhpcyBzaXR1YXRpb24gYXJlIGFib3V0IGVxdWFsLCB3ZSBjYW4gYWxzbyBjb21wdXRlIHRoZSBtZWRpYW4gaGVyZS4gV2UgYXJlIHVzaW5nIHZpc3VhbGlzYXRpb24gdG8gZGVtb25zdHJhdGUgdGhpcyBwcm9vZiAoQm94IHBsb3QgYW5kIEhpc3RvZ3JhbSkuDQoNCg0KYGBge3J9DQoNCmdncGxvdGx5KGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBBR0UpKSArDQogIGdlb21fYm94cGxvdChjb2xvciA9ICJSZWQiLCBmaWxsID0gImN5YW4iKSsNCiAgbGFicyh0aXRsZT0iRGlzdHJpYnV0aW9uIG9mIEFnZXMgZm9yIFdpbm5pbmcgQ2FuZGlkYXRlIiwgDQogICAgICAgeCA9ICJDb3VudCIsIHkgPSAiQWdlIG9mIFdpbm5pbmcgQ2FuZGlkYXRlIikpDQoNCmBgYA0KDQoNCkluIGFib3ZlIGJveHBsb3QgaXQgaXMgY2xlYXJseSBzaG93biB0aGF0IG1lZGlhbiBvZiBhZ2UgaXMgNTUuDQoNCmBgYHtyfQ0KDQpnZ3Bsb3RseShpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gQUdFKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDMsY29sb3IgPSAieWVsbG93IixmaWxsID0gInJlZCIpKw0KICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgQWdlcyBmb3IgV2lubmluZyBDYW5kaWRhdGUiLCANCiAgICAgICB5ID0gIkNvdW50IiwgeCA9ICJBZ2Ugb2YgV2lubmluZyBDYW5kaWRhdGUiKSApDQoNCmBgYA0KDQpJbiBhYm92ZSBIaXN0b2dyYW0gd2UgY2FuIHNheSB0aGF0IG1lYW4gaXMganVzdCBuZWFyIGFib3V0IDU0LjUwLiANCg0KDQojIDcuICBDaG9vc2UgYW5kIGNhbGN1bGF0ZSBhIG1lYXN1cmUgb2Ygc3ByZWFkIHRoYXQgaXMgYXBwcm9wcmlhdGUgZm9yIHlvdXIgY2hvc2VuIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gRXhwbGFpbiB3aHkgeW91IGNob3NlIHRoaXMgYXMgeW91ciBtZWFzdXJlIG9mIHNwcmVhZC4NCg0KV2UgaGF2ZSBmb2xsb3dpbmcgZmFjdG9ycyBmb3IgbWVhc3VyZSBvZiBzcHJlYWQgb3IgbWVhc3VyZSBvZiBkaXNwZXJzaW9uDQoxLiBSYW5nZQ0KMi4gSW50ZXItUXVhcnRpbGUgUmFuZ2UgDQozLiBWYXJpYW5jZQ0KNC4gTWVhbiBEZXZpYXRpb24gDQo1LiBTdGFuZGFyZCBEZXZpYXRpb24NCg0KYGBge3J9DQpzZChpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyJEFHRSkNCg0KYGBgDQoNCjxodG1sPjxwPkluIGFib3ZlIHF1ZXN0aW9uIHdlIHVzZSBTdGFuZGFyZCBEZXZpYXRpb24gYmVjYXVzZSBXaGVuIGRhdGEgaXMgZGlzdHJpYnV0ZWQgcmVsYXRpdmVseSBub3JtYWxseSwgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBwZXJmb3JtcyBleGNlcHRpb25hbGx5IHdlbGwgYW5kIHByb3ZpZGVzIGluZm9ybWF0aW9uIHNpbWlsYXIgdG8gdGhhdCBvZiB0aGUgSVFSLiBCdXQgdGhlIElRUiBpcyB0eXBpY2FsbHkgZmF2b3JlZCBmb3IgZGF0YSB0aGF0IGlzIG9idmlvdXNseSBub24tbm9ybWFsLkJ1dCBpbiBvdXIgY2FzZSBBZ2UgaXMganVzdCBub3JtYWxseSBkaXN0cmlidXRlZC48L3A+PGJyPiANCg0KDQoNCg0KDQo8UD48aDU+PHVsPkNhdGVnb3JpY2FsIFZhcmlhYmxlIDogPGI+Q0FURUdPUlk8L2I+PC91bD48YnI+DQoNCkZvciBlYWNoIGNhdGVnb3JpY2FsIHZhcmlhYmxlIDoNCg0KIyAxLiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgcGxvdCB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjb3VudHMgZm9yIHRoaXMgdmFyaWFibGUuIA0KDQoNCmBgYHtyfQ0KDQpnZ3Bsb3RseShpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gQ0FURUdPUlkpKSArDQogIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIixmaWxsID0gImN5YW4iKSsNCiAgbGFicyh0aXRsZT0iQ291bnQgb2YgRGlmZmVyZW50IENhdGVnb3JpZXMgb2YgV2lubmluZyBDYW5kaWRhdGUiLCANCiAgICAgICB5ID0gIkNvdW50IiwgeCA9ICJDYXRlZ29yeSIpICkNCg0KDQpgYGANCg0KDQojIDIuIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHByb3BvcnRpb25zIGZvciB0aGlzIHZhcmlhYmxlLg0KDQpgYGB7cn0NCnBpZV9kYXRhIDwtIHRhYmxlKGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIkQ0FURUdPUlkpDQoNCg0KDQpsYmxzIDwtIHBhc3RlKG5hbWVzKHBpZV9kYXRhKSwgIlxuIiwgcGllX2RhdGEsIHNlcD0iIikNCg0KcGllM0QocGllX2RhdGEsIGxhYmVscyA9IGxibHMsIA0KICAgICAgbWFpbiA9ICJQcm9wb3J0aW9ucyBvZiBEaWZmZXJlbnQgQ2F0ZWdvcmllcyBvZiBXaW5uaW5nIENhbmRpZGF0ZSIpDQoNCg0KDQpgYGANCg0KDQoNCg0KIyAzLiBEaXNjdXNzIGFueSB1bnVzdWFsIG9ic2VydmF0aW9ucyBmb3IgdGhpcyB2YXJpYWJsZT8NCg0KQW5zLS0+IFRoZXJlIGlzIG9ubHkgb25lIHVudXN1YWwgb2JzZXJ2YXRpb24gaW4gYWJvdmUgY2F0ZWdvcmljYWwgdmFyaWFibGUuIE91dCBvZiA1MzksIDU1IGFyZSBmcm9tIFNUIGNhdGVnb3J5IG9yIHdlIGNhbiBzYXkgdGhhdCBhcHJveCBvbmx5IDEwICUgb2YgY2FuZGlkYXRlcyBhcmUgZnJvbSBTVCBjYXRlZ29yeSB3aGljaCBpcyBsaWtlIGFuIG91dGxpZXIgb2Ygb3VyIGRhdGEuDQoNCiMgNC4gRGlzY3VzcyBpZiB0aGVyZSBhcmUgdG9vIGZldy90b28gbWFueSB1bmlxdWUgdmFsdWVzPw0KDQpBbnMtPiBUaGVyZSBhcmUgb25seSAzIHVuaXF1ZSB2YWx1ZXMgaW4gb3VyIGNhdGVnb3JpY2FsIHZhcmlhYmxlICBpLmUgR2VuZXJhbCBDYXRlZ29yeSwgU0MgQ2F0ZWdvcnkgYW5kIFNUIENhdGVnb3J5Ljxicj4NCg0KYGBge3J9DQp1bmlxdWUoaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciRDQVRFR09SWSkNCg0KYGBgDQoNCg0KDQoNCjxicj48UD48aDU+PHVsPjx1PkJpdmFyaWF0ZSBBbmFseXNpczwvdT48L3VsPjxicj4NCg0KPFA+PGg1Pjx1bD5PbmUgcGFpciBvZiBOdW1lcmljIFZhcmlhYmxlIDogPGI+QUdFPC9iPiBhbmQgPGI+R2VuZXJhbCBWb3RlczwvYj48L3VsPjxicj4NCg0KPFA+PGg1Pjx1bD5PbmUgcGFpciBvZiBOdW1lcmljICBhbmQgQ2F0ZWdvcmljYWwgVmFyaWFibGUgOiA8Yj5BR0U8L2I+IGFuZCA8Yj5DYXRlZ29yeTwvYj48L3VsPjxicj4NCg0KDQoNCiMgMS4gQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcy4NCg0KDQoxLiBGb3IgMXN0IFBhaXINCg0KYGBge3J9DQppbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyIDwtIGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXIgJT4lIG11dGF0ZShHRU5FUkFMLlZPVEVTPUdFTkVSQUwuVk9URVMvMTAwMDApDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQoNCmdncGxvdGx5KGluZGlhbl9lbGVjdGlvbl9kZl93aW5uZXJfc29ydCAlPiUgDQogICAgICAgIGdncGxvdChhZXMoeCA9IEFHRSwgeSA9IEdFTkVSQUwuVk9URVMpKSArDQogICAgICAgIGdlb21fcG9pbnQoKSArDQogICAgICAgIGdlb21fc21vb3RoKGZvcm11bGEgPSB5IH4geCwgbWV0aG9kID0gImxtIikgKw0KICAgICAgICBsYWJzKHRpdGxlPSJDb21hcHJpc29uIG9mIEFnZSBhbmQgR2VuZXJhbCBWb3RlcyIsDQogICAgICAgIHkgPSAiTm8uIG9mIEdlbmVyYWwgVm90ZXMiLCB4ID0gIiBBZ2UiKSkNCg0KYGBgDQoNCjIuIEZvciAybmQgUGFpcg0KDQpgYGB7cn0NCg0KZ2dwbG90bHkoaW5kaWFuX2VsZWN0aW9uX2RmX3dpbm5lciAlPiUgDQogIGdncGxvdChhZXMoeCA9IENBVEVHT1JZLCB5ID0gQUdFLCBmaWxsID0gQ0FURUdPUlkpKSArDQogIGdlb21fcG9pbnQoKSsNCiAgICANCiAgbGFicyh0aXRsZT0iQ29tYXByaXNvbiBvZiBDYXRlZ29yeSBhbmQgQWdlIG9mIFdpbm5pbmcgQ2FuZGlkYXRlcyAiLCANCiAgICAgICB5ID0gIkFnZSIsIHggPSAiQ2F0ZWdvcnkiKSkNCg0KDQpgYGANCg0KDQojIDIuIERlc2NyaWJlIHRoZSBmb3JtLCBkaXJlY3Rpb24sIGFuZCBzdHJlbmd0aCBvZiB0aGUgb2JzZXJ2ZWQgcmVsYXRpb25zaGlwLiBJbmNsdWRlIGJvdGggcXVhbGl0YXRpdmUgYW5kIHF1YW50aXRhdGl2ZSBtZWFzdXJlcywgYXMgYXBwcm9wcmlhdGUuDQoNCkFucy0tPiBXaGVuIGV4YW1pbmluZyBhIHNjYXR0ZXJwbG90IGFuZCBCb3hwbG90ICwgd2UgaGF2ZSB0byBiZSBhYmxlIHRvIGV4cGxhaW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMgdGhhdCB3ZSBvYnNlcnZlLg0KDQpUaGUgZm9ybSwgZGlyZWN0aW9uLCBhbmQgU3RyZW5ndGggb2YgdGhlIGNvbm5lY3Rpb24sIGFzIHdlbGwgYXMgdGhlIGV4aXN0ZW5jZSBvZiBhbnkgb3V0bGllcnMsIHNob3VsZCBhbHdheXMgYmUgaW5jbHVkZWQgaW4gYSBicmllZiBkZXNjcmlwdGlvbiBvZiB0aGUgYXNzb2NpYXRpb24gaW4gYSBzY2F0dGVycGxvdC4NCg0KRm9ybTogSXMgdGhlIHJlbGF0aW9uc2hpcCBvZiBlaXRoZXIgbGluZWFyIG9yIG5vbmxpbmVhci4gSGVyZSBpbiBvdXIgMXN0IGNhc2UgaXQgaXMgc2xpZ2hseSBzaG93aW5nIG5lZ2F0aXZlIGxpbmVhciByZWxhdGlvbiBhcyBBZ2UgaXMgaW5jcmVhc2luZyBuby4gb2Ygdm90ZXMgYXJlICBkZWNyZWFzaW5nLiANCg0KDQpTdHJlbmd0aDogRG9lcyBpdCBzZWVtIGFzIHRob3VnaCB0aGVyZSBpcyBhIHN0cm9uZywgZmFpcmx5IHN0cm9uZywgb3Igd2VhayBhc3NvY2lhdGlvbi4gSW4gb3VyIGNhc2UgdGhlcmUgaXMgd2VhayByZWxhdGlvbnNoaXAuIA0KDQpgYGB7cn0NCmNvcihpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyJEFHRSxpbmRpYW5fZWxlY3Rpb25fZGZfd2lubmVyJEdFTkVSQUwuVk9URVMpDQoNCg0KYGBgDQoNCg0KDQpEaXJlY3Rpb246IEl0IHRlbGxzIHdoZXRoZXIgdGhlIHJlbGF0aW9uc2hpcCBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gSW4gb3VyIGNhc2UgcmVsYXRpb25zaGlwIGlzIG5lZ2F0aXZlIGFuZCB3ZWFrLg0KDQoNCg0KDQojIDMuIEV4cGxhaW4gd2hhdCB0aGlzIHJlbGF0aW9uc2hpcCBtZWFucyBpbiB0aGUgY29udGV4dCBvZiB0aGUgZGF0YT8NCg0KQW5zLS0+IFRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGZvciB0aGUgdmFyaWFibGVzIGluZGljYXRlcyB0aGUgZGlyZWN0aW9uIG9mIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvLiBQb3NpdGl2ZSByZWxhdGlvbnNoaXBzIGFyZSBkZW5vdGVkIHdpdGggYSAicGx1cyIgc3ltYm9sLCB3aGVyZWFzIGJhZCByZWxhdGlvbnNoaXBzIGFyZSBkZW5vdGVkIGJ5IGEgIm1pbnVzIiBzaWduLg0KDQpQb3NpdGl2ZSAtLT4gV2hlbiB0d28gdmFyaWFibGVzIGFyZSBwb3NpdGl2ZWx5IGNvcnJlbGF0ZWQsIHRoZXkgYm90aCB0ZW5kIHRvIG1vdmUgaW4gdGhlIHNhbWUgZGlyZWN0aW9uOiBJZiBvbmUgZ3Jvd3MsIHRoZSBvdGhlciB1c3VhbGx5IGZvbGxvd3Mgc3VpdC4gT25lIHRlbmRzIHRvIGRpbWluaXNoIHdoZW4gdGhlIG90aGVyIGRvZXMgYXMgd2VsbC4NCg0KTmVnYXRpdmUgLS0+IFdoZW4gdHdvIHZhcmlhYmxlcyBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkLCB0aGV5IG9mdGVuIG1vdmUgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbnM6IGlmIG9uZSBncm93cywgdGhlIG90aGVyIHRlbmRzIHRvIGRyb3AsIGFuZCB2aWNlIHZlcnNhLg0KDQoNCg0KVGhlIGZvcm0gaXMgcmVmZXJlZCB0byB0aGUgd2hldGhlciByZWxhdGlvbnNoaXAgaXMgbGluZWFyIG9yIG5vbiBsaW5lYXIuDQoNCkxpbmVhci0tPkEgc3RyYWlnaHQgY29ubmVjdGlvbiBpcyByZWZlcnJlZCB0byBhcyBiZWluZyBsaW5lYXIgc2luY2UgaXQgcmVzZW1ibGVzIGEgc3RyYWlnaHQgbGluZS4NCg0KQ3VydmlsaW5lYXItLT4gQmVjYXVzZSBhIGN1cnZlZCBjb25uZWN0aW9uIHJlc2VtYmxlcyBhIGN1cnZlZCBsaW5lLCBpdCBpcyByZWZlcnJlZCB0byBhcyBiZWluZyBjdXJ2aWxpbmVhci4NCg0KDQoNCldlIGV4Y2x1c2l2ZWx5IHdvcmsgd2l0aCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgdGhhdCBtZWFzdXJlIGxpbmVhciByZWxhdGlvbnNoaXBzIGluIHRoaXMgVmFsdWUuIE90aGVyIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBleGlzdCB0aGF0IHF1YW50aWZ5IGN1cnZlZCByZWxhdGlvbnNoaXBzLCBidXQgdGhleSBhcmUgYWR2YW5jZWQgaW4gbmF0dXJlLg0KDQpQZXJmZWN0IFJlbGF0aW9uc2hpcC0tPlRoZSBjb2VmZmljaWVudCBvZiBjb3JyZWxhdGlvbiBpcyBlaXRoZXIgKzEuMDAgb3IgLTEuMDAgd2hlbiB0d28gdmFyaWFibGVzIGFyZSBsaW5lYXJseSBjb25uZWN0ZWQuIEVpdGhlciBmYXZvdXJhYmx5IG9yIG5lZ2F0aXZlbHksIGl0IGlzIGNsYWltZWQgdGhhdCB0aGV5IGFyZSBwcmVjaXNlbHkgbGluZWFybHkgY29ubmVjdGVkLg0KDQpObyBSZWxhdGlvbnNoaXAtLT5SZWxhdGlvbnNoaXA6IFdoZW4gdGhlcmUgaXMgYWJzb2x1dGVseSBubyBjb25uZWN0aW9uIGJldHdlZW4gdHdvIHZhcmlhYmxlcywgdGhlaXIgY29ycmVsYXRpb24gY29lZmZpY2llbnQgaXMgMC4wMC4NCg0KDQoNCkZvciBhbGwgdGhlc2UgdGhpbmdzIHdlIHVzZSBjb2VmZmljaWVudCBvZiBjb3JyZWxhdGlvbi4gUHJlZGljdGlvbnMgbWF5IGJlIG1hZGUgd2l0aCB0aGUgdXNlIG9mIGNvcnJlbGF0aW9ucy4gV2UgbWF5IGV4cGVjdCB0aGF0IHR3byB2YXJpYWJsZXMgd2lsbCBjb250aW51ZSB0byBjb3JyZWxhdGUgaW4gdGhlIGFoZWFkIGlmIHRoZXkgaGF2ZSBiZWVuIHNob3duIHRvIGRvIHNvIGluIHRoZSBwYXN0LiBUbyBmb3JlY2FzdCB0aGUgdmFsdWUgdGhhdCB0aGUgb3RoZXIgdmFyaWFibGUgd2lsbCBoYXZlIGluIHRoZSBmdXR1cmUsIHdlIG1heSB1dGlsaXNlIHRoZSB2YWx1ZSBvZiBvbmUgdmFyaWFibGUuDQoNCg0KDQoNCiMgNC4gRGVzY3JpYmUgdGhlIHZhcmlhYmlsaXR5IHRoYXQgeW91IG9ic2VydmUgaW4gdGhlIHBsb3QgYW5kIGhvdyB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzdHJlbmd0aCB5b3UgY2FsY3VsYXRlZCBpbiBuby4gMiBhYm92ZS4NCg0KDQo8aHRtbD48cD5WYXJpYW5jZS0tPiBUaGUgc3RhdGlzdGljYWwgYXNzZXNzbWVudCBvZiB0aGUgdmFyaWF0aW9uIGluIG51bWJlcnMgd2l0aGluIGEgZGF0YSBjb2xsZWN0aW9uIGlzIGtub3duIGFzIHZhcmlhbmNlLiBJbiBtb3JlIGRldGFpbCwgdmFyaWFuY2UgYXNzZXNzZXMgaG93IGZhciBhcGFydCBlYWNoIG51bWJlciBpbiB0aGUgY29sbGVjdGlvbiBpcyBmcm9tIHRoZSBtZWFuIChhdmVyYWdlKSBhbmQsIGNvbnNlcXVlbnRseSwgZnJvbSBlYWNoIG90aGVyLg0KVGhlIHNxdWFyZSByb290IG9mIHRoZSB2YXJpYW5jZSBpcyB0aGUgU3RhbmRhcmQgRGV2aWF0aW9uLiANCg0KV2UgY2FuIGxlYXJuIG1vcmUgYWJvdXQgb3VyIGRhdGEgdGhhbiB3aGF0IGlzIG9mdGVuIHNob3duIGJ5IGNvbnZlbnRpb25hbCBzdGF0aXN0aWNhbCBzdW1tYXJpZXMgYnkgdXNpbmcgYSBzY2F0dGVycGxvdCB0byB2aXN1YWxpc2UgaXQuIEJpdmFyaWF0ZSBkYXRhIGNhbiBiZSBzdW1tYXJpc2VkIHVzaW5nIG9uZSBvZiB0d28gZnVuZGFtZW50YWwgbWV0aG9kczogcmVncmVzc2lvbiBhbmFseXNpcyBvciBjb3JyZWxhdGlvbiBhbmFseXNpcy4gUmVncmVzc2lvbiBhbmFseXNpcyBkZXNjcmliZXMgaG93IHRvIGxldmVyYWdlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIGNvbXBvbmVudHMgdG8gZm9yZWNhc3Qgb3IgY29udHJvbCBvbmUgdmFyaWFibGUgdXNpbmcgdGhlIG90aGVyLiBUaGUgc3RhbmRhcmQgZXJyb3Igb2YgZXN0aW1hdGUgYW5kIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24sIGJvdGggZXF1YWwgdG8gdGhlIHNxdWFyZSBvZiB0aGUgY29ycmVsYXRpb24gciwgYXJlIHR3byBpbmRpY2F0b3JzIG9mIGhvdyB3ZWxsIGEgcmVncmVzc2lvbiBhbmFseXNpcyBwZXJmb3JtZWQuIFRoZSBmb3JtZXIgaW5kaWNhdGVzIHRoZSB0eXBpY2FsIHNpemUgb2YgcHJlZGljdGlvbiBlcnJvcnMsIHdoaWxlIHRoZSBsYXR0ZXIgaW5kaWNhdGVzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBZIHZhcmlhYmxlJ3MgdmFyaWFiaWxpdHkgdGhhdCBpcyAiZXhwbGFpbmVkIiBieSB0aGUgWCB2YXJpYWJsZS4NCg0KTm93LCBpbiBvdXIgZmlyc3Qgc2NhdHRlciBwbG90LCB3ZSBjYW4gb2JzZXJ2ZSB0aGF0IHRoZSBtYWpvcml0eSBvZiB0aGUgZGF0YSBpcyBwcmVzZW50IGZvciBib3RoIHRoZSB2YXJpYWJsZSB4IGFuZCB5IGF4aXMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgZ3JhcGguDQoNCkFjY29yZGluZyB0byBzdHJlbmd0aCBvZiBvdXIgZGF0YSBvdXIgc2NhdHRlciBwbG90IGlzIHdlYWsgaW4gcmVsYXRpb25zaGlwLiBJIG11c3Qgc2F5IGl0IGlzIG5lZ2F0aXZlIGluIHJlbGF0aW9uc2hpcC48YnI+DQoNCg0KDQoNCg0KPGJyPjxQPjxoMz48dWw+PGI+VHVsYWliIEJpbiBBeXl1YiAoMDc4OTE0MSk8L2I+PC91bD48YnI+DQo8UD48aDU+PHVsPjx1PlVuaXZhcmlhdGUgQW5hbHlzaXM8L3U+PC91bD48YnI+DQoNCjxQPjxoNT48dWw+TnVtZXJpYyBWYXJpYWJsZSA6IDxiPlBvc3RhbCBWb3RlczwvYj48L3VsPjxicj4NCg0KDQoNCmBgYHtyfQ0KZGZfaW5kX2VsZWMgPC0gcmVhZC5jc3YoIkluZGlhbl9FbGVjdGlvbl8yMDE5LmNzdiIpDQpkZl9pbmRfZWxlYw0KYGBgDQojVW5pdmFyaWF0ZSANCiNOdW1lcmljIHZhcmlhYmxlOg0KDQojIFF1ZXMxLiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgcGxvdCB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGlzIHZhcmlhYmxlLg0KDQpgYGB7cn0NCg0KZ2dwbG90bHkoZGZfaW5kX2VsZWMgJT4lIA0KICBnZ3Bsb3QoYWVzKFBPU1RBTC5WT1RFUykpKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDcwLCBjb2xvciA9ICJkYXJrYmx1ZSIpKw0KICAgIGxhYnModGl0bGUgPSAiRElTVFJJQlVUSU9OIE9GIFBPU1RBTCBWT1RFUyIsIHggPSAiTnVtYmVyIE9mIFBvc3RhbCBWb3RlcyIsIHkgPSAiQ291bnQiKSkNCg0KYGBgDQoNCg0KIyBRdWVzMi4gQ29uc2lkZXIgYW55IG91dGxpZXJzIHByZXNlbnQgaW4gdGhlIGRhdGEuIElmIHByZXNlbnQsIHNwZWNpZnkgdGhlIGNyaXRlcmlhIHVzZWQgdG8gaWRlbnRpZnkgdGhlbSBhbmQgcHJvdmlkZSBhIGxvZ2ljYWwgZXhwbGFuYXRpb24gZm9yIGhvdyB5b3UgaGFuZGxlZCB0aGVtLg0KDQpgYGB7cn0NCmdncGxvdGx5KGRmX2luZF9lbGVjICU+JSANCiAgICAgICAgICAgZ2dwbG90KGFlcyh5ID0gUE9TVEFMLlZPVEVTKSkrDQogICAgICAgICAgIGdlb21fYm94cGxvdChmaWxsID0gInNreWJsdWUiKSkNCmBgYA0KDQpBbnMyLiBBZnRlciBsb29raW5nIGF0IHRoZSBnZW5lcmF0ZWQgYm94cGxvdCwgd2UgY2FuIGNsZWFybHkgc2VlIHRoYXQgdGhlcmUgYXJlIG11bHRpcGxlIG91dGxpZXJzLiBUbyBoYW5kbGUgdGhlIG91dGxpZXJzIHdlIGNhbiBpbXB1dGUgdGhlbSB3aXRoIG1lZGlhbiBpZiB0aGV5IGFyZSBjbG9zZSB0byBtZWRpYW4gb3Igd2UgY2FuIGltcHV0ZSB0aGVtIHdpdGggYW55IHZhbHVlIGNsb3NlciB0byB0aGUgb3V0bGllcnMgd2hpY2ggaXMgbm90IGFuIG91dGxpZXIuDQoNCg0KIyBRdWVzMy4gRGVzY3JpYmUgdGhlIHNoYXBlIGFuZCBza2V3bmVzcyBvZiB0aGUgZGlzdHJpYnV0aW9uLg0KDQpgYGB7cn0NCm1lYW4oZGZfaW5kX2VsZWMkUE9TVEFMLlZPVEVTKQ0KYGBgDQpBbnMzLiBBZnRlciBmaW5kaW5nIHRoZSBtZWFuIGFib3ZlIGFuZCBtZWRpYW4gaW4gcXVlc3Rpb24gMiwgd2UgY2FuIHNheSB0aGF0IHRoZSBzaGFwZSBhbmQgc2tld25lc3Mgb2YgdGhlIGRpc3RyaWJ1dGlvbiBhcmUgdW5pbW9kZWwgYW5kIHJpZ2h0IHNrZXdlZCBiZWNhdXNlIG1vc3Qgb2YgdGhlIGRhdGEgYXJlIGluIGxlZnQgcGFydC4NCg0KDQojIFF1ZXM0LiBCYXNlZCBvbiB5b3VyIGFuc3dlciB0byB0aGUgcHJldmlvdXMgcXVlc3Rpb24sIGRlY2lkZSBpZiBpdCBpcyBhcHByb3ByaWF0ZSB0byBhcHBseSBhIHRyYW5zZm9ybWF0aW9uIHRvIHlvdXIgZGF0YS4gSWYgbm8sIGV4cGxhaW4gd2h5IG5vdC4gSWYgeWVzLCBuYW1lIHRoZSB0cmFuc2Zvcm1hdGlvbiBhcHBsaWVkIGFuZCB2aXN1YWxpemUgdGhlIHRyYW5zZm9ybWVkIGRpc3RyaWJ1dGlvbi4NCg0KDQoNCg0KYGBge3J9DQpkZl9pbmRfZWxlYyA8LSBkZl9pbmRfZWxlYyAlPiUNCiAgbXV0YXRlKHNxcnRfcHN0LnZvdGUgPSBzcXJ0KFBPU1RBTC5WT1RFUykpDQoNCmdncGxvdGx5KGRmX2luZF9lbGVjICU+JSANCiAgZ2dwbG90KGFlcyhzcXJ0X3BzdC52b3RlKSkrDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAsIGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikrDQogICAgbGFicyh0aXRsZSA9ICJESVNUUklCVVRJT04gVVNJTkcgU1FVQVJFIFJPT1QgVFJBTlNGT1JNQVRJT04iLCB4ID0gInNxcnQoUE9TVEFMIFZPVEVTKSIsIHkgPSAiQ291bnQiKSkNCmBgYA0KDQpBbnM0LiBBZnRlciB1c2luZyBMb2cxMCBUcmFuc2Zvcm1hdGlvbiBpdCBpcyBkaWZmaWN1bHQgdG8gaW50ZXJwcmV0IHRoZSB2aXN1YWxpemF0aW9uIGJlY2F1c2UgdGhlIGRhdGEgaGFzIHRvbyBtYW55IHplcm8gdmFsdWVzIHdoaWNoIGdpdmVzIHVzIG5lZ2F0aXZlIGluZmluaXR5Lg0KQW5kIGFmdGVyIHVzaW5nIHNxdWFyZSByb290IHRyYW5zZm9ybWF0aW9uIGl0IGlzIGVhc3kgdG8gaW50ZXJwcmV0IHRoZSBkaXN0cmlidXRpb24gd2hpY2ggaXMgaW4gYSBzaGFwZSBvZiB1bmltb2RlbCBhbmQgdGhlIGRpc3RyaWJ1dGlvbiBpcyByaWdodCBza2V3ZWQuDQoNCg0KIyBRdWVzNS4gQ2hvb3NlIGFuZCBjYWxjdWxhdGUgYW4gYXBwcm9wcmlhdGUgbWVhc3VyZSBvZiBjZW50cmFsIHRlbmRlbmN5Lg0KYGBge3J9DQptZWFuKGRmX2luZF9lbGVjJFBPU1RBTC5WT1RFUykNCmBgYA0KDQojIFF1ZXM2LiBFeHBsYWluIHdoeSB5b3UgY2hvc2UgdGhpcyBhcyB5b3VyIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gUHJvdmlkZSBzdXBwb3J0aW5nIGV2aWRlbmNlIGZvciB5b3VyIGNob2ljZS4NCg0KYGBge3J9DQpnZ3Bsb3RseShkZl9pbmRfZWxlYyAlPiUgZ2dwbG90KGFlcyh5ID0gUE9TVEFMLlZPVEVTKSkrDQogIGdlb21fYm94cGxvdChmaWxsID0gInNreWJsdWUiKSkNCmBgYA0KDQogQW5zNi4gQ2hvc2UgdGhpcyBiZWNhdXNlIGl0IGlzIHNob3dpbmcgdGhlIGF2ZXJhZ2Ugb2YgcG9zdGFsIHZvdGVzIHdoaWNoIGlzIHZlcnkgZGlmZmVyZW50IGluIGNvbXBhcmlzb24gdG8gdGhlIG1lZGlhbi4gSW4gdGhpcyBib3hwbG90IHdlIGNhbiBzZWUgdGhlIG1lZGlhbiBpcyBsb3cgaS5lLiwgMzE2LjAwIGFuZCB0aGUgbWVhbiB3YXMgOTkwLjcxMDYgYXMgd2Ugc2F3IGluIHByZXZpb3VzIGFuc3dlci4gDQoNCg0KIyBRdWVzNy4gQ2hvb3NlIGFuZCBjYWxjdWxhdGUgYSBtZWFzdXJlIG9mIHNwcmVhZCB0aGF0IGlzIGFwcHJvcHJpYXRlIGZvciB5b3VyIGNob3NlbiBtZWFzdXJlIG9mIGNlbnRyYWwgdGVuZGVuY3kuIEV4cGxhaW4gd2h5IHlvdSBjaG9zZSB0aGlzIGFzIHlvdXIgbWVhc3VyZSBvZiBzcHJlYWQuDQpgYGB7cn0NCnNkKGRmX2luZF9lbGVjJFBPU1RBTC5WT1RFUykNCmBgYA0KDQpBbnMuIFRvIGNhbGN1bGF0ZSBtZWFzdXJlcyBvZiBzcHJlYWQgd2UgY2FuIHVzZSBtaW5pbXVtIHZhbHVlLCBtYXhpbXVtIHZhbHVlLCBzdGFuZGFyZCBkZXZpYXRpb24sIHZhcmlhbmNlLCBpbnRlcnF1YXJ0aWxlKElRUiksIGV0Yy4gV2UgYXJlIHRha2luZyBzdGFuZGFyZCBkZXZpYXRpb24gYW5kIHRoZSB2YWx1ZSBpcyBoaWdoIHNvIHRoZSB2YWx1ZSBpbiB0aGUgZGF0YSBzZXQgYXJlIHNwcmVhZCBvdmVyIGEgd2lkZSByYW5nZS4NCg0KDQo8UD48aDU+PHVsPkNhdGVnb3JpY2FsIFZhcmlhYmxlIDogPGI+U3RhdGU8L2I+PC91bD48YnI+DQoNCg0KIyBDYXRlZ29yaWNhbCB2YXJpYWJsZToNCg0KIyBRdWVzMS4gQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgY291bnRzIGZvciB0aGlzIHZhcmlhYmxlLg0KDQpgYGB7cn0NCmdncGxvdGx5KGRmX2luZF9lbGVjICU+JSBnZ3Bsb3QoYWVzKFNUQVRFKSkrDQogIGdlb21fYmFyKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikrDQogICAgY29vcmRfZmxpcCgpKw0KICAgIGxhYnModGl0bGUgPSAiRElTVFJJQlVUSU9OIE9GIFNUQVRFUyIsIHggPSAiU3RhdGVzIiwgeSA9ICJDb3VudCIpKQ0KYGBgDQoNCg0KIyBRdWVzMi4gQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgcHJvcG9ydGlvbnMgZm9yIHRoaXMgdmFyaWFibGUuDQoNCmBgYHtyfQ0KZGZfaW5kX2VsZWMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IoMSksIGZpbGwgPSBmYWN0b3IoU1RBVEUpKSkrDQogIGdlb21fYmFyKHdpZHRoID0gMSkrDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gJ3knLCBzdGFydCA9IDApKw0KICBsYWJzKHRpdGxlID0gIlBST1BPUlRJT05TIE9GIERJRkZFUkVOVCBTVEFURVMiLCB4ID0gIlN0YXRlcyIpDQoNCg0KYGBgDQoNCg0KDQojIFF1ZXMzLiBEaXNjdXNzIGFueSB1bnVzdWFsIG9ic2VydmF0aW9ucyBmb3IgdGhpcyB2YXJpYWJsZT8NCg0KQW5zMy4gSGF2aW5nIHRvbyBtYW55IHZhbHVlIGluIHRoaXMgdmFyaWFibGUgd2hpY2ggaXMgbWFraW5nIGl0IGhhcmQgdG8gaW50ZXJwcmV0IHRoZSB2aXN1YWxpemF0aW9uLg0KDQoNCiMgUXVlczQuIERpc2N1c3MgaWYgdGhlcmUgYXJlIHRvbyBmZXcvdG9vIG1hbnkgdW5pcXVlIHZhbHVlcz8NCg0KYGBge3J9DQp1bmlxdWUoZGZfaW5kX2VsZWMkU1RBVEUpDQpgYGANCkFuczQuIFllcyB0aGVyZSBhcmUgdG9vIG1hbnkgdW5pcXVlIHZhbHVlcyBpLmUuLCAzNi4gDQoNCg0KDQo8YnI+PFA+PGg1Pjx1bD48dT5CaXZhcmlhdGUgQW5hbHlzaXM8L3U+PC91bD48YnI+DQoNCjxQPjxoNT48dWw+T25lIHBhaXIgb2YgTnVtZXJpYyBWYXJpYWJsZSA6IDxiPkFHRTwvYj4gYW5kIDxiPlBvc3RhbCBWb3RlczwvYj48L3VsPjxicj4NCg0KPFA+PGg1Pjx1bD5PbmUgcGFpciBvZiBOdW1lcmljICBhbmQgQ2F0ZWdvcmljYWwgVmFyaWFibGUgOiA8Yj5BR0U8L2I+IGFuZCA8Yj5XaW5uZXI8L2I+PC91bD48YnI+DQoNCg0KDQojIFF1ZXMxLiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgcGxvdCB0byB2aXN1YWxpemUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0d28gdmFyaWFibGVzLg0KDQpBbnMxLiANCjEuIFBsb3QgdXNpbmcgdHdvIG51bWVyaWNhbCB2YXJpYWJsZXMuDQpgYGB7cn0NCmRmX2luZF9lbGVjIDwtIGRmX2luZF9lbGVjICU+JSANCiAgICAgICAgICAgICAgICBtdXRhdGUoUE9TVEFMLlZPVEVTID0gUE9TVEFMLlZPVEVTLzEwMCkNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90bHkoZGZfaW5kX2VsZWMgJT4lIA0KICAgICAgICAgICBnZ3Bsb3QoYWVzKHggPSBBR0UsIHkgPSBQT1NUQUwuVk9URVMpKSsNCiAgICAgICAgICAgZ2VvbV9wb2ludChjb2xvciA9ICJza3libHVlIikrDQogICAgICAgICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnYW0iLCANCiAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIikpKQ0KYGBgDQoNCiAyLiBQbG90IHVzaW5nIG9uZSBudW1lcmljYWwgYW5kIG9uZSBjYXRlZ29yaWNhbCB2YXJpYWJsZS4NCmBgYHtyfQ0KZ2dwbG90bHkoZGZfaW5kX2VsZWMgJT4lDQogIGdncGxvdChhZXMoeCA9IFdJTk5FUiwgeSA9IEFHRSkpKw0KICBnZW9tX3BvaW50KGNvbG9yID0gInNreWJsdWUiKSkNCmBgYA0KDQojIFF1ZXMyLiBEZXNjcmliZSB0aGUgZm9ybSwgZGlyZWN0aW9uLCBhbmQgc3RyZW5ndGggb2YgdGhlIG9ic2VydmVkIHJlbGF0aW9uc2hpcC4gSW5jbHVkZSBib3RoIHF1YWxpdGF0aXZlIGFuZCBxdWFudGl0YXRpdmUgbWVhc3VyZXMsIGFzIGFwcHJvcHJpYXRlLg0KDQpgYGB7cn0NCmNvciggZGZfaW5kX2VsZWMkQUdFLCBkZl9pbmRfZWxlYyRQT1NUQUwuVk9URVMsIA0KICAgICB1c2UgPSAiY29tcGxldGUub2JzIikNCmBgYA0KDQpBbnMyLiBGb3JtIHRlbGxzIGlmIHRoZSByZWxhdGlvbnNoaXAgaXMgbGluZWFyIG9yIG5vbi1saW5lYXIgYW5kIGluIG91ciBjYXNlIHRoZSBmb3JtIGlzIHNob3dpbmcgbGluZWFyIGNvcnJlbGF0aW9uLg0KRGlyZWN0aW9uIHRlbGxzIGlmIHRoZSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBhbmQgaW4gb3VyIGNhc2UgaXQgaXMgc2hvd2luZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbi4NClN0cmVuZ3RoIHRlbGxzIHdlYXRoZXIgdGhlIGNvcnJlbGF0aW9uIGlzIHdlYWsgc3Ryb25nIG9yIGZhaXJseSBzdHJvbmcgIGFuZCBpbiBvdXIgY2FzZSB0aGUgcmVsYXRpb24gYmV0d2VlbiB2YXJpYWJsZXMgaXMgZmFpcmx5IHN0cm9uZyBpLmUuLCAwLjEyOTM2Lg0KDQoNCiMgUXVlczMuIEV4cGxhaW4gd2hhdCB0aGlzIHJlbGF0aW9uc2hpcCBtZWFucyBpbiB0aGUgY29udGV4dCBvZiB0aGUgZGF0YS4NCg0KQW5zMy4gVGhpcyByZWxhdGlvbnNoaXAgbWVhbnMgdG8gdW5kZXJzdGFuZCBhbmQgZmluZCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0d28gdmFyaWFibGVzLiBTbyB0aGF0IHdlIGNhbiBmaW5kIHRoZSBwb3NpdGl2ZSwgbmVnYXRpdmUsIGN1cnZpbGluZWFyIHJlbGF0aW9uc2hpcC4gV2UgY2FuIHNheSB0aGUgcmVsYXRpb25zaGlwIGlzIHBlcmZlY3QgaWYgdGhlIHZhbHVlIGxpZXMgYmV0d2VlbiAtMSB0byArMSBhbmQgYSBubyByZWxhdGlvbnNoaXAgd2hlbiBubyByZWxhdGlvbiBpcyBmb3VuZCBzbyB0aGUgY29ycmVsYXRpb24gaXMgMC4gDQpUbyBmaW5kIHRoZSByZWxhdGlvbnNoaXAgd2UgdXNlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50Lg0KDQoNCiMgUXVlczQuIERlc2NyaWJlIHRoZSB2YXJpYWJpbGl0eSB0aGF0IHlvdSBvYnNlcnZlIGluIHRoZSBwbG90IGFuZCBob3cgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgc3RyZW5ndGgNCnlvdSBjYWxjdWxhdGVkIGluICMyIGFib3ZlLg0KDQpBbnM0LiBCeSB1dGlsaXppbmcgYSBzY2F0dGVyIHBsb3QgdG8gdmlzdWFsaXplIG91ciBkYXRhLCB3ZSBtYXkgZGlzY292ZXIgbW9yZSBhYm91dCBpdCB0aGFuIHdoYXQgaXMgZnJlcXVlbnRseSBzaG93biBieSB0cmFkaXRpb25hbCBzdGF0aXN0aWNhbCBzdW1tYXJpZXMuIE9uZSBvZiB0aGUgdHdvIHByaW1hcnkgdGVjaG5pcXVlc+KAlGNvcnJlbGF0aW9uIGFuYWx5c2lzIG9yIHJlZ3Jlc3Npb24gYW5hbHlzaXPigJRjYW4gYmUgdXNlZCB0byBzdW1tYXJpemUgYml2YXJpYXRlIGRhdGEuIFJlZ3Jlc3Npb24gYW5hbHlzaXMgZXhwbGFpbnMgaG93IHRvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBjb25uZWN0aW9uIGJldHdlZW4gdGhlIHR3byBlbGVtZW50cyB0byBwcmVkaWN0IG9yIHJlZ3VsYXRlIG9uZSBwYXJhbWV0ZXIgdXNpbmcgdGhlIG90aGVyLiBUd28gbWVhc3VyZXMgb2YgaG93IHdlbGwgYSByZWdyZXNzaW9uIGFuYWx5c2lzIHdvcmtlZCBhcmUgdGhlIHN0YW5kYXJkIGVycm9yIG9mIGVzdGltYXRlIGFuZCBjb2VmZmljaWVudCBvZiBkZXRlcm1pbmF0aW9uLCBib3RoIGVxdWFsIHRvIHRoZSBzcXVhcmUgb2YgdGhlIGNvcnJlbGF0aW9uIHIuIEluZGljYXRlZCBieSB0aGUgbGF0dGVyIGlzIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBZIHZhcmlhYmxlJ3MgdmFyaWFiaWxpdHkgdGhhdCBjYW4gYmUgImV4cGxhaW5lZCIgYnkgdGhlIFggdmFyaWFibGUsIHRoZSBmb3JtZXIgaW5kaWNhdGluZyB0aGUgYXZlcmFnZSBzaXplIG9mIHByZWRpY3Rpb24gbWlzdGFrZXMuDQpTY2F0dGVyIHBsb3Qgc2hvd3MgYSByYXRoZXIgZ29vZCBhbmQgZmFpcmx5IHN0cm9uZyByZWxhdGlvbnNoaXAgd2l0aCB0aGUgcXVhbGl0eSBvZiBvdXIgZGF0YSBhbmQgaXQgaXMgYSBwb3NzaWJseSBwb3NpdGl2ZSByZWxhdGlvbnNoaXANCg0KDQoNCg0KDQoNCg0KDQoNCjxicj48UD48aDM+PHVsPjxiPkFsaXNoYSBNYWhhamFuKDA4MDI2MzEpPC9iPjwvdWw+PGJyPg0KPFA+PGg1Pjx1bD48dT5Vbml2YXJpYXRlIEFuYWx5c2lzPC91PjwvdWw+PGJyPg0KDQo8UD48aDU+PHVsPk51bWVyaWMgVmFyaWFibGUgOiA8Yj5HRU5FUkFMIFZPVEVTPC9iPjwvdWw+PGJyPg0KDQoNCg0KYGBge3J9IA0KaW5kX2VsZWMgPC0gcmVhZC5jc3YoIkluZGlhbl9lbGVjdGlvbl8yMDE5LmNzdiIpDQoNCmBgYA0KDQojIDEuIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoaXMgdmFyaWFibGUuDQoNCmBgYHtyfQ0KDQppbmRfZWxlYyA8LSBpbmRfZWxlYyAlPiUNCiAgbXV0YXRlKEdFTkVSQUwuVk9URVMgPSBHRU5FUkFMLlZPVEVTLzEwMDApDQpgYGANCg0KDQpgYGB7cn0NCg0KDQpnZ3Bsb3QoaW5kX2VsZWMsIGFlcyh4ID0gR0VORVJBTC5WT1RFUykpKw0KICBnZW9tX2hpc3RvZ3JhbSggY29sb3IgPSAiQkxVRSIsIGZpbGwgPSAiWUVMTE9XIikgKw0KICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgZ2VuZXJhbCB2b3RlcyBpbiAyMDE5IGVsZWN0aW9uIiwgDQogICAgICAgeSA9ICJDb3VudCIsIHggPSAiTm8uIG9mIGdlbmVyYWwgdm90ZXMiKSANCmBgYA0KDQpJbiB0aGUgYWJvdmUgaGlzdG9ncmFtLCBpdCBjYW4gYmUgc2VlbiB0aGF0IHRoZXJlIGlzIHJpZ2h0IHNrZXdlZCBkaXN0cmlidXRpb24gd2hlcmUgZ2VuZXJhbCB2b3RlcyBsaWVzIG1vc3RseSBvbiBsZWZ0IHNpZGUuDQoNCiMgMi5Db25zaWRlciBhbnkgb3V0bGllcnMgcHJlc2VudCBpbiB0aGUgZGF0YS4gSWYgcHJlc2VudCwgc3BlY2lmeSB0aGUgY3JpdGVyaWEgdXNlZCB0byBpZGVudGlmeSB0aGVtIGFuZCBwcm92aWRlIGEgbG9naWNhbCBleHBsYW5hdGlvbiBmb3IgaG93IHlvdSBoYW5kbGVkIHRoZW0uDQoNCmBgYHtyfQ0KZ2dwbG90bHkoaW5kX2VsZWMgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBHRU5FUkFMLlZPVEVTKSkgKw0KICBnZW9tX2JveHBsb3QoY29sb3IgPSAiUmVkIiwgZmlsbCA9ICJibHVlIikrDQogIGxhYnModGl0bGU9IkRpc3RyaWJ1dGlvbiBvZiBHZW5lcmFsIHZvdGVzIGluIDIwMTkgZWxlY3Rpb24iLCANCiAgICAgICB4ID0gIkNvdW50IiwgeSA9ICJHZW5lcmFsIFZvdGVzIikpDQpgYGANCkluIGFib3ZlIGJveCBwbG90LCBpdCBjYW4gYmUgc2VlbiB0aGF0IHRoZXJlIGFyZSBtYW55IG91dGxpZXJzIGluIHRoaXMgcGxvdCB3aGljaCBjYW4gYmUgY2FsY3VsYXRlZCBhczoNCg0KIEludGVycXVhcnRpbGUgKElRUikgPSBRMy1RMQ0KICAgICAgICAgICAgICAgICAgICAgPSA0ODUuODEgLSAyMS4wMw0KICAgICAgICAgICAgICAgICAgICAgPSA0NjQuNzgNCg0KcG9zc2libGUgb3V0bGllcnM6ICAgdmFsdWVzID4gPSBRMyArIDEuNSAqIElRUiAoY2FwcGluZykgYW5kIHZhbHVlcyA8ID0gUTEgLSAxLjUgKiBJUVIgKGZsb29yaW5nKQ0KIA0KIHZhbHVlcyA+ID0gMTE4Mi45OCBhbmQgdmFsdWVzIDwgPSAtNjc2LjE0IA0KIA0KIFNvLCBhY2NvcmRpbmcgdG8gdGhpcyBmb3JtdWxhLCB0aGVyZSBpcyBubyBvdXRsaWVycyBpbiB0aGlzIHBsb3QuIGJ1dCBpbiBteSBhbmFseXNpcyB0aGVyZSBhcmUgc29tZSBvdXRsaWVycyB3aGljaCBmYWxscyBiZXR3ZWVuIDQ4NS44MSBhbmQgMTA2Ni44Mi4NCiANCiBIb3cgdG8gaGFuZGVsIG91dGxpZXJzOiANCiANCiAxLiBmaXJzdCB3YXkgdG8gaGFuZGxlIHRoZXNlIG91dGxpZXJzIGlzIHRvIHNpbXBseSBkZWxldGUgaXQgb3IgcmVtb3ZlIGl0LiBCdXQgdGhpcyBpcyBub3QgYW4gYXBwcm9wcmlhdGUgd2F5Lg0KIDIuIHNlY29uZCB3YXkgaXMgdG8gYXNzaWduIHRoYXQgdmFsdWUgd2hpY2ggaXMgbmVhcmVyIHZhbHVlLg0KIDMuIEFuZCBUaGlyZCB3YXkgaXMgdG8gZmluZCB0aGUgbWVhbiwgaWYgaXQgaXMgbmVhcmJ5IHRoZSB2YWx1ZXMgdGhlbiB3ZSB0YWtlIHRoYXQgdmFsdWUuIA0KIA0KIA0KIyAzLiBEZXNjcmliZSB0aGUgc2hhcGUgYW5kIHNrZXduZXNzIG9mIHRoZSBkaXN0cmlidXRpb24/DQpBbnM6IFRoZSBzaGFwZSBvZiB0aGUgZGlzdHJpYnV0aW9uIGlzIHVuaW1vZGVsIGFzIGl0IGhhcyBvbmUgaHVtcCBhbmQgaXQgY2FuIGJlIGNsZWFybHkgc2VlbiB0aGF0IHRoZXJlIGlzIHJpZ2h0IHNrZXdlZCBkaXN0cmlidXRpb24gd2hlcmUgZ2VuZXJhbCB2b3RlcyBsaWVzIG1vc3RseSBvbiBsZWZ0IHNpZGUuDQogDQogDQojIDQuIEJhc2VkIG9uIHlvdXIgYW5zd2VyIHRvIHRoZSBwcmV2aW91cyBxdWVzdGlvbiwgZGVjaWRlIGlmIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGFwcGx5IGEgdHJhbnNmb3JtYXRpb24gdG8geW91ciBkYXRhLiBJZiBubywgZXhwbGFpbiB3aHkgbm90LiBJZiB5ZXMsIG5hbWUgdGhlIHRyYW5zZm9ybWF0aW9uIGFwcGxpZWQgYW5kIHZpc3VhbGl6ZSB0aGUgdHJhbnNmb3JtZWQgZGlzdHJpYnV0aW9uLg0KIA0KYGBge3J9DQogc3VtbWFyeShpbmRfZWxlYyRHRU5FUkFMLlZPVEVTKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShsb2cxMChpbmRfZWxlYyRHRU5FUkFMLlZPVEVTKSkNCmBgYA0KYGBge3J9DQpzdW1tYXJ5KHNxcnQoaW5kX2VsZWMkR0VORVJBTC5WT1RFUykpDQpgYGANCg0KYGBge3J9DQppbmRfZWxlYyRsb2dfZ3ZvdGUgPC0gbG9nMTAoaW5kX2VsZWMkR0VORVJBTC5WT1RFUykNCmBgYA0KDQoNCmBgYHtyfQ0KDQoNCmdncGxvdGx5KGluZF9lbGVjICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbG9nX2d2b3RlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShjb2xvciA9ICJ5ZWxsb3ciLGZpbGwgPSAicmVkIixiaW5zID0gMjApKw0KICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgTG9nMTAoR0VORVJBTCBWT1RFUykgZm9yIENhbmRpZGF0ZSIsIA0KICAgICAgIHkgPSAiQ291bnQiLCB4ID0gIkxvZzEwKEdlbmVyYWwgVm90ZXMgb2YgQ2FuZGlkYXRlKSIpICkNCmBgYA0KIA0KYGBge3J9DQppbmRfZWxlYyRzcXJ0X2d2b3RlcyA9IHNxcnQoaW5kX2VsZWMkR0VORVJBTC5WT1RFUykNCmBgYA0KIA0KIA0KYGBge3J9DQoNCmdncGxvdGx5KGluZF9lbGVjICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3FydF9ndm90ZXMpKSArDQogIGdlb21faGlzdG9ncmFtKGNvbG9yID0gInllbGxvdyIsZmlsbCA9ICJyZWQiLGJpbnMgPSAyMCkrDQogIGxhYnModGl0bGU9IkRpc3RyaWJ1dGlvbiBvZiBTUVJUKEdFTkVSQUwgVk9URVMpIGZvciBDYW5kaWRhdGUiLCANCiAgICAgICB5ID0gIkNvdW50IiwgeCA9ICJTUVJUKEdlbmVyYWwgVm90ZXMgb2YgQ2FuZGlkYXRlKSIpICkNCg0KYGBgDQpBZnRlciBjb21wYXJpbmcgYWJvdmUgMyBwbG90cywgMSBpbiBxdWVzdGlvbiAybmQgYW5kIDIgaW4gcXVlc3Rpb24gNHRoIGkuZS4gbG9nMTAgYW5kIHNxcnQsIGl0IGNhbiBiZSBkZWNpZGVkIHRoYXQgd2UgY2FuIHRha2UgSXN0IHBsb3Qgd2hpY2ggaXMgc3ltbWV0cmljYWwgcmF0aGVyIHRoYXQgb3RoZXIgdHdvIHBsb3RzIHRoYXQgYXJlIG5vdCBzeW1tZXRyaWNhbChmb3JtaW5nIDIgaHVtcHMuKQ0KIA0KIyA1IC4gQ2hvb3NlIGFuZCBjYWxjdWxhdGUgYW4gYXBwcm9wcmlhdGUgbWVhc3VyZSBvZiBjZW50cmFsIHRlbmRlbmN5LiANCkFuczogQ2VudHJhbCB0ZW5kZW5jeTogVGhlIHN0YXRpc3RpY2FsIG1lYXN1cmUgdGhhdCBkZXNpZ25hdGVzIG9uZSB2YWx1ZSBhcyBiZWluZyByZXByZXNlbnRhdGl2ZSBvZiBhIHdob2xlIGRpc3RyaWJ1dGlvbiBpcyBrbm93biBhcyBjZW50cmFsIHRlbmRlbmN5LiBbMl0gVGhlIGNvbXBsZXRlIHNldCBvZiBkYXRhIHdpbGwgYmUgYWNjdXJhdGVseSBkZXNjcmliZWQuIEl0IGlzIHRoZSBzaW5nbGUgdmFsdWUgdGhhdCBiZXN0IGNoYXJhY3Rlcml6ZXMgb3IgZW5jYXBzdWxhdGVzIHRoZSBpbmZvcm1hdGlvbiBnYXRoZXJlZC4NCg0KTWVhbiwgbWVkaWFuIGFuZCBtb2RlIGFyZSB0aHJlZSB3YXlzIHRoYXQgYXJlIHVzZWQgdG8gbWVhc3VyZSBjZW50cmFsIHRlbmRlbmN5Lg0KDQpgYGB7cn0NCm1lZGlhbl92YWx1ZSA8LSBtZWRpYW4oaW5kX2VsZWMkR0VORVJBTC5WT1RFUykNCm1lZGlhbl92YWx1ZQ0KDQpgYGANCg0KYGBge3J9DQptZWFuX3ZhbHVlIDwtIG1lYW4oaW5kX2VsZWMkR0VORVJBTC5WT1RFUykNCm1lYW5fdmFsdWUNCmBgYA0KIyA2LiBFeHBsYWluIHdoeSB5b3UgY2hvc2UgdGhpcyBhcyB5b3VyIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gUHJvdmlkZSBzdXBwb3J0aW5nIGV2aWRlbmNlIGZvciB5b3VyIGNob2ljZSAuDQpBbnM6IEFmdGVyIGFuYWx5emluZyBjZW50cmFsIHRlbmRlbmN5IGZvciBtZWFuIGFuZCBtZWRpYW4gb2YgdmFyaWFibGUgZ2VuZXJhbCB2b3RlcywgSSB0YWtlIG1lYW4gYXMgdGhlIG1lYXN1cmUgZm9yIGNlbnRyYWwgdGVuZGVuY3kgYmVjYXVzZSBpdCBpdCBtb3JlIGFjY3VyYXRlIHRoYW4gbWVkaWFuIGFuZCBhbHNvIG91ciBkYXRhIGlzIG1vc3RseSBvbiBsZWZ0IHNpZGUgYW5kIGFsc28gd2UgYXJlIGNhbGN1bGF0ZWQgYXZlcmFnZSBvZiBnZW5lcmFsICB2b3Rlcy4gc28sIG1lYW4gaXMgYmVzdCBzdWl0ZWQgZm9yIHRoaXMgdmFyaWFibGUuDQoNCg0KIyA3LiBDaG9vc2UgYW5kIGNhbGN1bGF0ZSBhIG1lYXN1cmUgb2Ygc3ByZWFkIHRoYXQgaXMgYXBwcm9wcmlhdGUgZm9yIHlvdXIgY2hvc2VuIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gRXhwbGFpbiB3aHkgeW91IGNob3NlIHRoaXMgYXMgeW91ciBtZWFzdXJlIG9mIHNwcmVhZC4NCkFuczoNCldlIGNhbiBjYWxjdWxhdGUgbWVhc3VyZSBvZiBzcHJlYWQgaW4gbWFueSB3YXlzIGxpa2UgUmFuZ2UsIElRUiwgVmFyaWFuY2UsIE1lYW4gZGV2aWF0aW9uLCBTdGFuZGFyZCBkZXZpYXRpb24uIGJ1dCBoZXJlIEkgYW0gY2FsY3VsYXRpbmcgdmFyaWFuY2UgZm9yIGdlbmVyYWwgdm90ZXM6DQpgYGB7cn0NCnZhcihpbmRfZWxlYyRHRU5FUkFMLlZPVEVTKQ0KDQpgYGANClRoZSBhdmVyYWdlIHNxdWFyZWQgZGV2aWF0aW9uIGZyb20gdGhlIG1lYW4sIGFsc28ga25vd24gYXMgdmFyaWFuY2UsIGdpdmVzIHVzIHRoZSBhdmVyYWdlIGRpc3BlcnNpb24gZnJvbSB0aGUgbWVhbiBmb3IgYSBnaXZlbiBzZXQgb2YgZGF0YS4gSG93ZXZlciwgaWYgYW4gb3V0bGllciBpcyBwcmVzZW50LCB0aGUgdmFsdWUgcmV0dXJuZWQgYWZ0ZXIgc3F1YXJpbmcgdGhlIGRldmlhdGlvbiBmcm9tIHRoZSBtZWFuIHdvdWxkIGJlIGV4Y2Vzc2l2ZWx5IGxhcmdlLCB3aGljaCBpbW1lZGlhdGVseSBsZWFkcyB1cyB0byB0aGUgY29uY2x1c2lvbiB0aGF0IGFuIG91dGxpZXIgaXMgcHJlc2VudCBpbiB0aGUgZGF0YSBzZXQuIFdoZW4geW91IGNhbGN1bGF0ZSB0aGUgdmFyaWFuY2UsIHlvdSdsbCBzZWUgdGhhdCB0aGUgcmVzdWx0IGlzIGFibm9ybWFsbHkgaGlnaCBpbiB0aGUgYmlnIHBpY3R1cmUuIFdlIGJhc2ljYWxseSB0YWtlIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGVzZSBudW1iZXJzIHRvIHJlc3RvcmUgdGhlbSB0byB0aGVpciBub3JtYWwgdmFsdWUgYW5kIGdpdmUgdXMgYSBudW1iZXIgdGhhdCBpcyBtdWNoIG1vcmUgdHlwaWNhbCBpbiBvcmRlciB0byBhY2NvdW50IGZvciB0aGlzLg0KDQoNCjxicj48UD48aDU+PHVsPkNhdGVnb3JpY2FsIFZhcmlhYmxlIDogPGI+RURVQ0FUSU9OPC9iPjwvdWw+PGJyPg0KDQojIDEuQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgY291bnRzIGZvciB0aGlzIHZhcmlhYmxlLg0KDQpgYGB7cn0NCmdncGxvdGx5KGluZF9lbGVjICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gRURVQ0FUSU9OKSkgKw0KICBnZW9tX2Jhcihjb2xvciA9ICJiTFVFIixmaWxsID0gIlBJTksiKSsNCiAgbGFicyh0aXRsZT0iQ291bnQgb2YgRWR1Y2F0aW9uIENhbmRpZGF0ZSIsIA0KICAgICAgIHkgPSAiQ291bnQiLCB4ID0gIkVkdWNhdGlvbiIpICkNCmBgYA0KIyAyLiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgcGxvdCB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwcm9wb3J0aW9ucyBmb3IgdGhpcyB2YXJpYWJsZS4NCg0KYGBge3J9DQoNCmluZF9lbGVjICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKDEpLCBmaWxsID0gZmFjdG9yKEVEVUNBVElPTikpKSsNCiAgZ2VvbV9iYXIoIHdpZHRoID0gMSkrDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gJ3knLCBzdGFydCA9IDApKw0KICBsYWJzKHRpdGxlPSJQcm9wb3J0aW9ucyBvZiBFZHVjYXRpb24gb2YgQ2FuZGlkYXRlIiwgDQogICAgICAgeSA9ICJDb3VudCIsIHggPSAiRWR1Y2F0aW9uIikgDQogIA0KDQoNCmBgYA0KDQoNCiMgMy4gRGlzY3VzcyBhbnkgdW51c3VhbCBvYnNlcnZhdGlvbnMgZm9yIHRoaXMgdmFyaWFibGUuDQpBbnM6IFRoZXJlIGFyZSBzb21lIHVudXN1YWwgb2JzZXJ2YXRpb25zIG9mIEVkdWN0YWlvbiBjYXRlZ29yaWNhbCB2YXJpYWJsZSBsaWtlIA0KDQoxLiBJbiBzb21lIG9ic2VydmF0aW9ucyB0aGVyZSBhcmUgZHVwbGljYXRlIHZhbHVlcy4NCjIuIEluIHNvbWUgb2YgdGhlIGNhc2VzIHRoZXJlIGFyZSBtaXNzaW5nIHZhbHVlcy4NCjMuIEluIHRoaXMgdmFyaWFibGUgc29tZSB2YWx1ZXMgYXJlICJOb3QgQXZhaWxhYmxlIg0KDQoNCiMgNC4gRGlzY3VzcyBpZiB0aGVyZSBhcmUgdG9vIGZldy90b28gbWFueSB1bmlxdWUgdmFsdWVzPw0KQW5zOlRoZXJlIGFyZSB0b3RhbCAxMyB1bmlxdWUgdmFsdWVzLCB3ZSBoYXZlIGluIHRoaXMgY2F0ZWdvcmljYWwgdmFyaWFibGUuDQoNCmBgYHtyfQ0KdW5pcXVlKGluZF9lbGVjJEVEVUNBVElPTikNCmBgYA0KDQoNCjxicj48UD48aDU+PHVsPjx1PkJpdmFyaWF0ZSBBbmFseXNpczwvdT48L3VsPjxicj4NCg0KPFA+PGg1Pjx1bD5PbmUgcGFpciBvZiBOdW1lcmljIFZhcmlhYmxlIDogPGI+QUdFPC9iPiBhbmQgPGI+VG90YWwgVm90ZXM8L2I+PC91bD48YnI+DQoNCjxQPjxoNT48dWw+T25lIHBhaXIgb2YgTnVtZXJpYyAgYW5kIENhdGVnb3JpY2FsIFZhcmlhYmxlIDogPGI+QUdFPC9iPiBhbmQgPGI+U1RBVEU8L2I+PC91bD48YnI+DQoNCiMgMS4gQ3JlYXRlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gdmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcy4NCg0KYGBge3J9DQoNCmluZF9lbGMgPC0gaW5kX2VsZWMgJT4lIA0KICAgICAgICAgICAgbXV0YXRlKFRPVEFMLlZPVEVTPVRPVEFMLlZPVEVTLzEwMDApDQoNCg0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90bHkoaW5kX2VsYyU+JSANCiAgICAgICAgZ2dwbG90KGFlcyh4ID0gQUdFLCB5ID0gVE9UQUwuVk9URVMsIGNvbG9yID0gQ0FURUdPUlkpKSArDQogICAgICAgIGdlb21fcG9pbnQoKSArDQogICAgICAgIGdlb21fc21vb3RoKGZvcm11bGEgPSB5IH4geCwgbWV0aG9kID0gImxtIikgKw0KICAgICAgICBsYWJzKHRpdGxlPSJDb21wYXJpc29uIG9mIEFnZSBhbmQgVG90YWwgVm90ZXMiLA0KICAgICAgICB5ID0gIk5vLiBvZiBUb3RhbCBWb3RlcyIsIHggPSAiIEFnZSIpKQ0KDQpgYGANCg0KDQoyLiBGb3IgMm5kIHBhaXIgDQoNCmBgYHtyfQ0KDQpnZ3Bsb3RseShpbmRfZWxjICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gQUdFLCB5ID0gU1RBVEUsIGZpbGwgPSBTVEFURSkpICsNCiAgZ2VvbV9wb2ludCgpKw0KICAgIA0KICBsYWJzKHRpdGxlPSJDb21wYXJpc29uIG9mIFN0YXRlIGFuZCBBZ2Ugb2YgQ2FuZGlkYXRlcyAiLCANCiAgICAgICB5ID0gIlN0YXRlIiwgeCA9ICJBZ2UiKSkNCg0KDQpgYGANCiMgMi4gRGVzY3JpYmUgdGhlIGZvcm0sIGRpcmVjdGlvbiwgYW5kIHN0cmVuZ3RoIG9mIHRoZSBvYnNlcnZlZCByZWxhdGlvbnNoaXAuIEluY2x1ZGUgYm90aCBxdWFsaXRhdGl2ZQ0KYW5kIHF1YW50aXRhdGl2ZSBtZWFzdXJlcywgYXMgYXBwcm9wcmlhdGUuIA0KDQpBbnMtLT4gSW4gYSBzY2F0dGVycGxvdCwgYSBxdWljayBzdW1tYXJ5IG9mIHRoZSBsaW5rIHNob3VsZCBhbHdheXMgaW5jbHVkZSB0aGUgZm9ybSwgZGlyZWN0aW9uLCBhbmQgc3RyZW5ndGggb2YgdGhlIGNvbm5lY3Rpb24gYXMgd2VsbCBhcyB0aGUgcHJlc2VuY2Ugb2YgYW55IG91dGxpZXJzLg0KDQpGb3JtOiBJcyB0aGUgcmVsYXRpb25zaGlwIG9mIGVpdGhlciBsaW5lYXIgb3Igbm9ubGluZWFyLiBIZXJlIGluIG91ciAxc3QgY2FzZSBpdCBpcyBzbGlnaGx5IHNob3dpbmcgcG9zaXRpdmUgbGluZWFyIHJlbGF0aW9uIGFzIEFnZSBpcyBpbmNyZWFzaW5nIG5vLiBvZiBUb3RhbCB2b3RlcyBhcmUgIEluY3JlYXNpbmcuDQoNClN0cmVuZ3RoIDogSXQgdGVsbHMgdXMgaG93IHN0cm9uZyBpcyByZWxhdGlvbiBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMsIGVpdGhlciB3ZWFrLCBzdHJvbmcgb3IgZmFpcmx5IHN0cm9uZy4gQnV0IGluIHRoaXMgY2FzZSBPdXIgcmVsYXRpb24gaXMgZmFpcmx5IHN0cm9uZyBhbmQgcG9zaXRpdmUuIEhlcmUgYmVsb3cgd2UgYXJlIGNhbGN1bGF0aW5nIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IHdpdGhpbiB0d28gdmFyaWFibGVzLg0KDQoNCmBgYHtyfQ0KDQpjb3IoaW5kX2VsYyRBR0UsIGluZF9lbGMkVE9UQUwuVk9URVMsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KDQpgYGANCkRpcmVjdGlvbjogSXQgdGVsbHMgd2hldGhlciB0aGUgcmVsYXRpb25zaGlwIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLiBJbiBvdXIgY2FzZSByZWxhdGlvbnNoaXAgaXMgUG9zaXRpdmUgYW5kIGZhaXJseSBzdHJvbmcuDQoNCiMgMyBFeHBsYWluIHdoYXQgdGhpcyByZWxhdGlvbnNoaXAgbWVhbnMgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGRhdGEuDQoNCkFucy0tPiBVbmRlcnN0YW5kaW5nIGFuZCBkZXRlcm1pbmluZyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0d28gdmFyaWFibGVzIGlzIHdoYXQgdGhpcyBjb25uZWN0aW9uIHJlZmVycyB0by4gaW4gb3JkZXIgdG8gaWRlbnRpZnkgdGhlIGN1cnZpbGluZWFyLCBwb3NpdGl2ZSwgYW5kIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcHMuIElmIHRoZSB2YWx1ZSBpcyBiZXR3ZWVuIC0xIGFuZCArMSwgdGhlbiB0aGUgcmVsYXRpb25zaGlwIGlzIHBlcmZlY3Q7IG90aGVyd2lzZSwgdGhlcmUgaXMgbm8gYXNzb2NpYXRpb24sIGFuZCB0aGUgY29ycmVsYXRpb24gaXMgMC4NCldlIHV0aWxpemUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IHRvIGRpc2NvdmVyIHRoZSByZWxhdGlvbnNoaXAuDQpJbiBvdXIgY2FzZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBpcyBwb3NpdGl2ZSBpLmUgKyAwLjIwOA0KDQojIDQgRGVzY3JpYmUgdGhlIHZhcmlhYmlsaXR5IHRoYXQgeW91IG9ic2VydmUgaW4gdGhlIHBsb3QgYW5kIGhvdyB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzdHJlbmd0aA0KeW91IGNhbGN1bGF0ZWQgaW4gIzIgYWJvdmUuDQoNCkFucy0tPiBUaGUgVmFyaWFuY2UgaXMgdGhlIG51bWVyaWNhbCBtZWFzdXJlIG9mIGhvdyB0aGV3IGRhdGEgaXMgc3ByZWFkIGFjcm9zcyB0aGUgbWVhbi4gVGhlIFIgbGFuZ3VhZ2UncyB2YXIoKSBmdW5jdGlvbiBjYWxjdWxhdGVzIGEgdmVjdG9yJ3Mgc2FtcGxlIHZhcmlhbmNlLiBJdCBzZXJ2ZXMgYXMgYSBnYXVnZSBmb3IgaG93IG11Y2ggYSB2YWx1ZSBkZXZpYXRlcyBmcm9tIHRoZSBtZWFuLiBUaGUgc3F1YXJlIHJvb3Qgb2YgdGhlIHZhcmlhbmNlIGlzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24uIA0KDQpUd28gbWVhc3VyZXMgb2YgaG93IHdlbGwgYSByZWdyZXNzaW9uIGFuYWx5c2lzIHdvcmtlZCBhcmUgdGhlIHN0YW5kYXJkIGVycm9yIG9mIGVzdGltYXRlIGFuZCBjb2VmZmljaWVudCBvZiBkZXRlcm1pbmF0aW9uLCBib3RoIGVxdWFsIHRvIHRoZSBzcXVhcmUgb2YgdGhlIGNvcnJlbGF0aW9uIHIuIEluZGljYXRlZCBieSB0aGUgbGF0dGVyIGlzIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBZIHZhcmlhYmxlJ3MgdmFyaWFiaWxpdHkgdGhhdCBjYW4gYmUgImV4cGxhaW5lZCIgYnkgdGhlIFggdmFyaWFibGUsIHRoZSBmb3JtZXIgaW5kaWNhdGluZyB0aGUgYXZlcmFnZSBzaXplIG9mIHByZWRpY3Rpb24gbWlzdGFrZXMuDQoNCk5vdyBpbiBvdXIgZmlyc3QgU2NhdHRlciBwbG90IG1vc3Qgb2YgdGhlIGRhdGEgaXMgcHJlc2VudCBpbiB0aGUgYm90dG9tIG9mIHRoZSBncmFwaCwgd2hpY2ggbWVhbnMgbW9zdGx5IHZhbHVlcyBvZiB0b3RhbCB2b3RlcyBhcmUgbGVzcy4NCg0KDQpBY2NvcmRpbmcgdG8gc3RyZW5ndGggb2Ygb3VyIGRhdGEgb3VyIHNjYXR0ZXIgcGxvdCBpcyBmYWlybHkgc3Ryb25nIGluIHJlbGF0aW9uc2hpcC4gSSBtdXN0IHNheSBpdCBpcyBwb3NpdGl2ZSByZWxhdGlvbi4NCg0K